PhxQueue是微信开源的一款基于Paxos协议实现的高可用、高吞吐和高可靠的分布式队列,保证At-Least-Once Delivery。在微信内部广泛支持微信支付、公众平台等多个重要业务。
作者:Junjie Liang, Tao He, Haochuan Cui, Qing Huang and Jiatao Xu
联系我们:phxteam@tencent.com
-
同步刷盘,入队数据绝对不丢,自带内部实时对账
-
出入队严格有序
-
多消费组
-
出队限速
-
出队重放
-
所有模块均可平行扩展
-
存储层批量刷盘、同步,保证高吞吐
-
存储层支持同城多中心部署
-
存储层自动容灾/接入均衡
-
消费者自动容灾/负载均衡
git clone https://github.com/Tencent/phxqueue
cd phxqueue/
bash build.sh
所有模块构建完成,现在可以启动一个简单的PhxQueue了。
下载phxqueue.tar.gz并解压到$PHXQUEUE_DIR
.
-
选择一个目录
$DEP_PREFIX
作为安装依赖的路径:export $DEP_PREFIX='/your/directory/for/dependency'
-
Protocol Buffers和glog
编译Protocol Buffers和glog,注意必须使用编译参数
./configure CXXFLAGS=-fPIC --prefix=$DEP_PREFIX
。然后创建软链接:rm -r $PHXQUEUE_DIR/third_party/protobuf/ rm -r $PHXQUEUE_DIR/third_party/glog/ ln -s $DEP_PREFIX $PHXQUEUE_DIR/third_party/protobuf ln -s $DEP_PREFIX $PHXQUEUE_DIR/third_party/glog
-
LevelDB
编译LevelDB到
$PHXQUEUE_DIR/third_party/leveldb/
,然后ln -s out-static lib
。 -
PhxPaxos和PhxRPC
编译PhxPaxos到
$PHXQUEUE_DIR/third_party/phxpaxos/
;编译 PhxRPC到$PHXQUEUE_DIR/third_party/phxrpc/
。 -
libco
使用Git clone libco到
$PHXQUEUE_DIR/third_party/colib/
。
cd $PHXQUEUE_DIR/
make
PhxQueue的目录结构如下:
phxqueue/ .................... PhxQueue根目录
├── bin/ ..................... 生成的二进制文件
├── etc/ ..................... 配置文件模板
├── lib/ ..................... 生成的库文件
├── phxqueue/ ................ PhxQueue源文件
├── phxqueue_phxrpc/ ......... PhxQueue的PhxRPC实现
└── ...
输出文件在bin/
和lib/
,示例配置文件在etc/
。
编译好的PhxQueue源代码目录可以直接运行简单的演示。
PhxQueue需要同时使用多个文件描述符。请保证设置ulimit -Sn
和ulimit -n
到足够大(4000以上)。
启动3个Store节点(加-d
参数可以在后台运行):
bin/store_main -c etc/store_server.0.conf
bin/store_main -c etc/store_server.1.conf
bin/store_main -c etc/store_server.2.conf
可以查看Store的日志:
ps -ef | grep store_main
tail -f log/store.0/store_main.INFO
tail -f log/store.1/store_main.INFO
tail -f log/store.2/store_main.INFO
注意: 正常运行需要启动至少2个Store节点,否则会出现如下错误日志:
MASTERSTAT: ERR: Propose err. paxos_ret 404 ...
启动3个Consumer节点:
bin/consumer_main -c etc/consumer_server.0.conf
bin/consumer_main -c etc/consumer_server.1.conf
bin/consumer_main -c etc/consumer_server.2.conf
可以查看Consumer的日志:
ps -ef | grep consumer_main
tail -f log/consumer.0/consumer_main.INFO
tail -f log/consumer.1/consumer_main.INFO
tail -f log/consumer.2/consumer_main.INFO
现在简单的PhxQueue已经部署完成!使用工具就可以发送测试请求了:
bin/test_producer_echo_main
你会看到Producer的输出:
produce echo succeeded!
我们回到Consumer看输出(3个中只有1个会处理请求并输出)
consume echo succeeed! ...
bin/producer_benchmark_main 10 5 5 10
再次观看Consumer的日志:
tail -f log/consumer.0/consumer_main.INFO
tail -f log/consumer.1/consumer_main.INFO
tail -f log/consumer.2/consumer_main.INFO
你会发现有类似这样的Consumer消费出队请求的日志:
INFO: Dequeue ret 0 topic 1000 consumer_group_id 1 store_id 1 queue_id 44 size 1 prev_cursor_id 9106 next_cursor_id 9109
在运行PhxQueue的过程中,会产生大量的日志和数据。运行log/clear_log.sh
以清理日志,运行data/clear_data.sh
以删除数据。删除前务必确认数据已经没有用。
通常,每个节点应该部署在一台机器上,针对每个节点修改etc/*.conf
中的内容。
在etc/
目录下,有以下这些文件
globalconfig.conf .................全局配置
topicconfig.conf ................. 主题配置
storeconfig.conf ................. Store配置
consumerconfig.conf ...............Consumer配置
schedulerconfig.conf ..............Scheduler配置
lockconfig.conf ...................Lock配置
将这些文件部署在所有目标机器上,并做相应的修改。
Store是队列的存储,使用Paxos协议作副本同步。
将以下3个配置文件分别部署到3个Store节点并启动:
bin/store_main -c etc/store_server.0.conf -d
bin/store_main -c etc/store_server.1.conf -d
bin/store_main -c etc/store_server.2.conf -d
Consumer是队列的消费者,以批量拉取的方式从Store拉数据。
将以下3个配置文件分别部署到3个Consumer节点并启动:
bin/consumer_main -c etc/consumer_server.0.conf -d
bin/consumer_main -c etc/consumer_server.1.conf -d
bin/consumer_main -c etc/consumer_server.2.conf -d
Lock是一个分布式锁,其接口设计非常通用化,使用者可以选择将Lock独立部署,提供通用分布式锁服务。部署Lock可以避免队列的重复消费。
如果不使用Lock,topicconfig.conf
中需要设置skip_lock = 1
。
将以下3个配置文件分别部署到3个Lock节点并启动:
bin/lock_main -c etc/lock_server.0.conf -d
bin/lock_main -c etc/lock_server.1.conf -d
bin/lock_main -c etc/lock_server.2.conf -d
Scheduler收集Consumer全局负载信息, 对Consumer做容灾和负载均衡。当使用者没有这方面的需求时,可以省略部署Scheduler,此时各Consumer根据配置权重决定与队列的处理关系。
Scheduler依赖Lock,如果需要部署Scheduler,请先部署Lock。
如果不使用Scheduler,topicconfig.conf
中需要设置use_dynamic_scale = 0
。
将以下3个配置文件分别部署到3个Scheduler节点并启动:
bin/scheduler_main -c etc/scheduler_server.0.conf -d
bin/scheduler_main -c etc/scheduler_server.1.conf -d
bin/scheduler_main -c etc/scheduler_server.2.conf -d
各个模块的日志位于'log/'下模块名子目录中,例如store的0号节点日志:
tail -f log/store.0/store_main.INFO
PR代码请遵守Google C++ 风格指南。