此文是编译过程的一个详细记录,如果想跳过各种坑,看精简的步骤,参见:phxpaxos编译 完整流程(精简版)
Paxos是分布式一致性算法中最基础和最著名的算法,没有之一。从Lamport正式公开发表Paxos论文算起,整整20周年。每个人在理解了一个算法后,往往都要思考一个问题,这个算法如何实现、能用在哪里。为了知道这两个问题,我在github上搜寻Paxos的项目,最高星(1900星)的是腾讯微信后台团队出品的phxpaxos,既然语言是C++,那么编译走起~
参考资料:官方的中文详细编译手册
当然我这里的步骤更加详细,几乎记录了过程中遇到的所有大坑小坑,按此记录,一步步来应该都能成功。
没有git请先安装:
yum -y install git
git clone --recursive https://github.com/tencent-wechat/phxpaxos.git
官方:使用- -recursive参数可以同时获得所依赖的第三方库leveldb, protobuf, glog源码。也可自行下载这些源码,然后自行拷贝或者通过软链的形式放置到third_party目录。
一开始用的Centos 6.5 minimal,下载这一步就卡死了。
首先,git clone报错:
>>> error: while accessing https://github.com/tencent-wechat/phxpaxos.git/info/refs
>>> fatal: HTTP request failed
这可能是git版本问题:
git --version
>>> git version 1.7.1
这是yum安装自带的git版本,那么尝试升级git:
1)安装相关依赖:
yum -y install curl-devel expat-devel gettext-devel openssl-devel zlib-devel asciidoc
yum -y install gcc gcc-c++ perl-ExtUtils-MakeMaker
2)卸载旧版本:
yum -y remove git
3)依次执行:
wget https://github.com/git/git/archive/v2.2.1.tar.gz
tar zxvf v2.2.1.tar.gz
cd git-2.2.1
make configure
./configure --prefix=/usr/local/git --with-iconv=/usr/local/libiconv
make install
echo "export PATH=$PATH:/usr/local/git/bin" >> /etc/bashrc
source /etc/bashrc
4)验证:
git --version
>>> git version 2.2.1
至此,git v2.2.1的编译安装已经完成。
注:如果过程中报错:
>>> Can’t locate ExtUtils/MakeMaker.pm in @INC
可能是忘记了这一步依赖:
yum install perl-ExtUtils-MakeMaker
git升级后再次执行安装命令,这次换了个报错:
>>> fatal: unable to access 'https://github.com/tencent-wechat/phxpaxos.git/': SSL connect error
这可能是nss版本太老,无法访问https域名。输入以下命令解决:
yum -y update nss
至此,CentOS下的git clone https://…安装问题已经彻底解决。
官方:我们的编译流程是基于leveldb1.18版本,如果你自行下载了其他版本,可能有编译上的不同。
我就是在上一步直接用- -recursive参数下载的leveldb,按照官方手册的步骤,执行以下命令:
cd phxpaxos/third_party/leveldb
make
然而,并没有在当前产生libleveldb.a文件……
试了几次,编译总是到此戛然而止:
>>> g++ -pthread -I. ...... -o out-static/leveldbutil
最后我不得不怀疑,自动下载的leveldb文件是有问题的。
去github上的releases特意找Release 1.18版本的源码下载,下载地址: https://github.com/google/leveldb/releases
删掉自动下载的,把自己下载的更名为leveldb,放到third_party/目录下。
然后按照官方的步骤就可以成功编译leveldb:
cd phxpaxos/third_party/leveldb // 进入目录
make // 编译完成后会在当前目录生成libleveldb.a文件。
成功make的最后输出:
>>> ar: 正在创建 libleveldb.a
继续执行:
mkdir lib
cd lib
ln -s ../libleveldb.a libleveldb.a // 建立一个软链,PhxPaxos通过lib这个目录来寻址静态库。
按照官方手册的步骤,执行以下命令:
cd phxpaxos/third_party/protobuf
./autogen.sh
如果提示:
>>> ./autogen.sh:行43: autoreconf: 未找到命令
去坑5吧。
不出意外地又出问题了:
>>> Google Mock not present. Fetching gmock-1.7.0 from the web...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:01:14 --:--:-- 0
可能因为长城的原因,一直卡在这里,那么就要继续填新坑了。
也许可以这么下载:
git clone https://github.com/paulsapps/gmock-1.7.0
但其实在third_party/目录下已经有了一个gmock文件夹,直接拷贝到third_party/protobuf文件夹下即可。
然后在执行./autogen.sh命令时可能还会有以下错误:
>>> configure.ac:93: error: possibly undefined macro: AC_PROG_LIBTOOL
If this token and others are legitimate, please use m4_pattern_allow.
See the Autoconf documentation.
>>> autoreconf: /usr/bin/autoconf failed with exit status: 1
安装下列依赖解决:
yum -y install libtool libsysfs-dev
如果还是报错,重新下载项目文件,把protobuf拷贝过来,执行以下命令:
libtoolize --copy --force
然后按照官方的步骤就可以成功编译protobuf:
cd phxpaxos/third_party/protobuf
./autogen.sh
成功的输出如下:
>>> + exit 0
继续执行:
./configure CXXFLAGS=-fPIC --prefix=[当前目录绝对路径]
有如下输出,暂时无影响:
=== configuring in gmock (/root/git/phxpaxos/third_party/protobuf/gmock)
configure: WARNING: no configuration information is in gmock
继续:
make && make install
至此,protobuf编译完成,编译完成后检查是否在当前目录成功生成bin,include,lib三个子目录。
cd PhxPaxos/
./autoinstall.sh
make && make install //默认使用-O2编译优化参数,如需编译debug版本,则命令为make debug=y
至此,PhxPaxos静态库编译完成,检查是否在当前目录成功生成lib子目录,并检查在lib目录是否成功生成静态库libphxpaxos.a.
cd phxpaxos/third_party/glog
./configure CXXFLAGS=-fPIC -prefix=[当前目录绝对路径]
make && make install
每个环节必报错的魔咒:
>>> cd . && automake-1.14 --gnu
/bin/sh:line 4: automake-1.14: command not found
make: *** [Makefile.in] error 1
[root@localhost glog]# make && make install
cd . && automake-1.14 --gnu
/bin/sh:line 4: automake-1.14: command not found
make: *** [Makefile.in] error 1
下面要安装automake-1.14。注意下列命令只能安装1.13.4:
yum -y install automake
另外,如果还碰到以下报错:
>>> aclocal-1.14: command not found
不要怀疑,你进入了坑5。
坑里无坑,直接执行:
wget http://ftp.gnu.org/gnu/automake/automake-1.14.tar.gz
wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz
tar xvzf autoconf-2.69.tar.gz
cd autoconf-2.69
yum -y install libtool libsysfs-dev
./configure
make && make install
tar xvzf automake-1.14.tar.gz
cd automake-1.14
./configure
make && make install
automake --version
>>> automake (GNU automake) 1.14
然后按照官方的步骤就可以成功编译glog:
cd phxpaxos/third_party/glog
./configure CXXFLAGS=-fPIC -prefix=[当前目录绝对路径]
make && make install
注:make那步可能还有如下错误:
>>> cd . && automake-1.14 --gnu
configure.ac:13: error: version mismatch. This is Automake 1.14,
configure.ac:13: but the definition used by this AM_INIT_AUTOMAKE
configure.ac:13: comes from Automake 1.14.1. You should recreate
configure.ac:13: aclocal.m4 with aclocal and run automake again.
parallel-tests: error: required file './test-driver' not found
parallel-tests: 'automake --add-missing' can install 'test-driver'
make: *** [Makefile.in] error 1
那就按照提示来吧:
automake --add-missing
aclocal-1.14
make && make install
至此,glog编译完成,检查是否在当前目录成功生成lib子目录,并检查在lib目录是否成功生成静态库libglog.a.
此处无坑:
cd PhxPaxos/plugin
make && make install
至此,PhxPaxos Plugin静态库编译成功,检查上层lib目录下是否成功生成静态库libphxpaxos_plugin.a.
源码已经跟随第一步下载到third_party/文件夹下,官网手册里没有编译它的步骤实乃大坑。因为不编译它,会在编译sample/phxecho中报错:
>>> g++: error:/root/git/phxpaxos/third_party/gflags/lib/libgflags.a:No such file or directory
yum -y install cmake
cd phxpaxos/third_party/gflags
cmake .
make -j 24
make install
至此,gflags静态库编译成功,检查是否在当前目录成功生成lib子目录,并检查在lib目录是否成功生成静态库libgflags.a
cd phxpaxos/sample/phxecho
make
mkdir log
在最简单模式下,我们使用一个服务器,在上面启动三个使用不同端口号的进程来模拟三个节点:
# 第一个参数是当前节点的地址信息;后续参数表示集群所有节点的地址信息
./phxecho 127.0.0.1:11111 127.0.0.1:11111,127.0.0.1:11112,127.0.0.1:11113
./phxecho 127.0.0.1:11112 127.0.0.1:11111,127.0.0.1:11112,127.0.0.1:11113
./phxecho 127.0.0.1:11113 127.0.0.1:11111,127.0.0.1:11112,127.0.0.1:11113
每个进程都保持如下的阻塞状态:
run paxos ok
echo server start, ip 127.0.0.1 port 11113
please input: <echo req value>
随意选择其中某个进程,在其终端输入”hello, chao”,结果如下:
hello, chao
[SM Execute] ok, smid 1 instanceid 0 value hello, chao
echo resp value hello, chao
其他两个进程会显示如下:
[SM Execute] ok, smid 1 instanceid 0 value hello, chao