一,问题背景 # 多进程之间需要传输大量数据的时候,比如多进程 RPC 框架的进程之间通信,常用共享内存队列。
但是共享内存队列难免会有 入队+出队 2次 memcpy 。
而且要变长共享内存队列,如果支持多生产者进程+多消费者进程 ,就要处理线程安全方面的问题, 比较麻烦。
process_vm_readv() , process_vm_writev() 是 Linux 3.2 新增的 syscall,用于在多个进程的地址空间之间,高效传输大块数据。
https://www.man7.org/linux/man-pages/man2/process_vm_readv.2.html
https://github.com/open-mpi/ompi/blob/master/opal/mca/btl/sm/btl_sm_get.c#L96
在此, 我提个设想,可以用 process_vm_readv 实现一个多进程内存队列,相比之下,优势是:
在处理 多线程/多进程 并发时,更简单 省掉一次 memcpy。 下面 demo 代码演示了这个思路。 为了方便,直接用 posix mq 来传输 iovec 数组,也没有考虑多路复用。 真实项目可能需要 eventfd 之内的机制来做 notify。
实测了下,3个进程加起来有 5.5 GB/秒 的速度。
一,介绍 # 比赛题目很简单:构造一个程序,在 stdout 上打印出自身的 MD5,程序越短越好。按最终程序文件大小字节数排名,文件越小,排名越靠前。 只能使用 ld-linux-x86-64.so, libc.so, libdl.so, libgcc_s.so, libm.so, libstdc++.so 。 禁止了 socket, shmget, fork, execvc 等 syscall 。
汇编高手如云,本人只做到 752 字节,只拿到 27 名。 但忙活好几天,学到不少东西,也有苦劳,还是值得记录一下。
基本是纯 C 实现,没有动用汇编。
1. 问题 # 一个 C++ 程序,如果 throw 了 exception ,但是又没有 catch,那么一般会产生 coredump, 问题是,在 gcc 4.x 版本产生的 coredump 文件中,没有 throw 时候的堆栈信息,导致不知道是哪里 throw 的,没法查问题。
原因是 gcc 4.x 的 /libstdc++-v3/src/c++11/thread.cc:92 里面有个 catch(…),所以 stack unwind 了,就没了 throw 时候的 stack 。
void * execute_native_thread_routine(){ try { ... }catch(...){ std::terminate(); } } https://abcdabcd987.com/libstdc++-bug/
一个解决办法是可以升级 GCC 7 ,或者可以用更简单的办法:
一,背景介绍 # ElasticSearch 是由 Lucene 包装上分布式复制一致性算法等附加功能,构成的开源搜索引擎系统。
近两年在业界热度大增,主要有 3 种应用场景:
全文搜索引擎 NOSQL 数据库 日志分析数据库 ELK 很多垂直领域搜索需求,都可以基于 ElasticSearch 来设计架构。
ElasticSearch 能大幅度提升相关业务的迭代开发速度,实现类似 sql 数据库增删改查一样的快速开发。 并在相对高 qps 的在线业务中,保证毫秒级的延迟,提供极高的可用性和稳定性。
经过持续的研读官方文档,调研业界经验,并在实践中应用反思后,总结出一套架构方案。供参考,欢迎意见建议。
一,问题背景 # 很多时候,我们需要确保进程只有一个实例运行。
有几种方法:
http://stackoverflow.com/questions/2964391/preventing-multiple-process-instances-on-linux
http://stackoverflow.com/questions/5339200/how-to-create-a-single-instance-application-in-c-or-c
https://github.com/qtproject/qt-solutions/tree/master/qtsingleapplication/src
比较常规的做法,是对一个文件加文件锁 flock,比如对 pid 文件 flock( LOCK_EX|LOCK_NB )
但是这种方法有些弊端:
如果文件被 mv 或者 rm,是会被绕过的。 如果磁盘故障比如磁盘满,目录没有写权限,会失败。 二,abstract namespace unix socket # http://linux.die.net/man/7/unix
unix socket 有3种:
基于文件的 socketpair 创建的,匿名的 abstract namespace 的,Linux特有 Linux 下, AF_UNIX socket 支持一种特殊的 abstract namespace unix socket 。
相比 普通的基于文件系统的 unix socket,abstract namespace unix socket :
没有磁盘文件 进程挂了以后自动删除,无残留文件 无需担心与 文件系统上的文件冲突,不需要关心文件系统上的绝对路径是否存在的问题
可以对抗输入数据模式的排序算法。
quick sort 在输入数据接近有序的情况下,效率不高。
Pattern-defeating quicksort (pdqsort) is a novel sorting algorithm that combines the fast average case of randomized quicksort with the fast worst case of heapsort, while achieving linear time on inputs with certain patterns. pdqsort is an extension and improvement of David Mussers introsort. All code is available for free under the zlib license.
借助 ext4 文件系统的 打洞 功能,可以实现一个消息队列 https://gist.github.com/CAFxX/571a1558db9a7b393579
fallocate(fd, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE, offset, length); Punching holes in files
https://lwn.net/Articles/415889/
怎样对大文件的中间部分进行增删?
首先,如果复制/写文件的后半段的话,肯定是可以实现的,但是这样不“高效”。 所以这里的需求是 “怎样在大文件中间 insert 或者 delete 一段数据而不用读写文件的后半部分”。
TrafficServer 是Apache基金会的 HTTP/HTTP2 代理服务器。
TrafficServer 的 HTTP2 部分主要的代码在 :
trafficserver/proxy/http2/HTTP2.h, HTTP2.cc trafficserver/proxy/http2/Http2Stream.h, Http2Stream.cc trafficserver/proxy/http2/Http2ClientSession.h, Http2ClientSession.cc trafficserver/proxy/http2/Http2ConnectionState.h, Http2ConnectionState.cc trafficserver/proxy/http2/ Http2DependencyTree.h, Http2DependencyTree.cc trafficserver/proxy/http2/HPACK.h, HPACK.cc trafficserver/proxy/http2/HuffmanCodec.h, HuffmanCodec.cc
Proxygen 的整体架构 一个 HTTPSession 对应一个 tcp 连接。
HTTPSession 中包含HTTPCodec ,HTTPCodec用来在 HTTPMessage(Request/Response) 和 字节流之间做转换(就是解析/序列化)。
一个 HTTPTransaction 对应一个 HTTP2 的Stream ,也就是一次 Req/Resp Handler 是业务逻辑处理的基类。
问题背景 # https://timyang.net/programming/load-average/
2015.08.13 高可用架构群 Load 编程比赛,Tim 在群征集一段代码使 load average 最高
多线程写几个 while 循环的方法太 trivial 了,就不提了。
下面是 byronhe 的两个解:
近日需要给服务器做备份,在网上找到了一个现成的金山快盘的api:https://github.com/deren/python-kuaipan (感谢!)
试了一下,遂决定备份到金山快盘上。
简单几行 python 代码实现一个 http 代理
libpcap驱动了tcpdump,和wireshark这类抓包工具.提供了高度灵活的包过滤语言. 据wikipedia,高性能的包过滤最早是在bsd上作为一个问题被解决,被称为bpf,在内核实现了一个解释器,进行包匹配,用户态提供一个字符设备, linux作为后来者,支持与bsd基本相同的packet filter,称为lpf,不同的是,linux是通过在一个raw socket来支持包过滤的,通过setsockopt来SO_ATTACH_FILTER,挂载过滤器. strace 可知,libpcap实际上进行了如下syscall:
socket(PF_PACKET, SOCK_RAW, 768) = 59 setsockopt(59, SOL_SOCKET, SO_ATTACH_FILTER, "\1\0\0\0\0\0\0\0\250\327Vc\375\177\0\0", 16) = 0 参考资料 # libpcap的api文档和demo代码可以参见
http://www.tcpdump.org/pcap3_man.html http://www.tcpdump.org/sniffex.c 实现 # 参考文档了demo,我写了一个小的sniffer,
思路类似 http://bazaar.launchpad.net/~lenzgr/mylvmbackup/trunk/view/head:/mylvmbackup.pl.in
#!/bin/sh bk_to="/var/mysql-backup-`date +%Y-%m-%d-%k-%M-%S |tr -d ' '`" user_name="root" user_pw="dev" sql=" flush tables with read lock; system cp -pR /var/lib/mysql $bk_to; unlock tables; " mysql -u $user_name -p$user_pw -e "$sql" echo $sql tar cjf $bk_to.bz2 $bk_to rm -rf $bk_to
用于监控apache,如果退出就自动重启apache,原理是在如果apache退出,则apache的pid文件会被close,或触发attrib事件, 只要用inotify监控这个事件,然后重启apache,再重新监控pid文件即可。
LAMP环境的一般入侵,大致经过sql注入,上传webshell,本地提权至root,安装rootkit等步骤。
采用如下的配置,mod_chroot和单独分区挂载可以让本地提权变得极为困难,而mod-security可以封堵一般的sql注入等应用层攻击。