转 -- Riak源码阅读手记系列文章

原址如下:

http://blog.nosqlfan.com/html/3066.html

http://www.54chen.com/_linux_/riak-source.html

Riak源码阅读手记系列文章

Riak是一个类Dynamo模型的key-value存储,用Erlang实现,并由Basho公司开源并主要开发维护。本文推荐的系列文章来自五四陈科学院,作者是@54chen(陈臻)。系列文章已经发表五篇,内容短小精悍而又内容丰富,推荐给大家,NoSQLFan会保持后续更新。

 

riak源码阅读手记一 初出茅庐 项目入口

riak

简介
basho(相扑)是一家美国的技术公司,专营数据存储和管理软件,11年6月30日获得了750万美元的融资。basho将riak开源,通过收取riak的维护和管理界面软件的使用费用来赚钱,和resin的公司类似。
今天主要研究的是,basho旗下的riak:一个类dynamo系统的kv存储。riak使用了erlang进行开发,将代码精简到极致。

rebar
riak的代码使用了一个叫做rebar(钢筋)的erlang构建工具,使用起来真的很方便,其使用方法建议参考这篇文章:http://www.linezing.com/blog/?p=347。每个项目下,都有一个叫做rebar.config的文件,里面用erlang语法记录了这个项目需要的目录、环境、版本、以及依赖的包在github上的位置。真的很方便。riak项目中,rebar和reltool被大量使用。reltool使用方法参见 http://erlangdisplay.iteye.com/blog/508944

riak的总控工程:https://github.com/basho/riak。
看rebar.config定义的依赖部分:

{deps, [
{cluster_info, "1.1.*", {git, "git://github.com/basho/cluster_info", {branch, "master"}}}, %% 这个模块提供了一个松散易扩展的导出集群节点状态的办法。可以收集的信息包括:时间、所有的erlang进程的静态统计、网络连接情况、cpu和内存、大队列进程、内部内存调用统计、ETS、各节点的名字版本等
{luwak, "1.*", {git, "git://github.com/basho/luwak", {branch, "master"}}}, %% 大对象存储。用来存音频视频啥的。
{riak_kv, "0.14.*", {git, "git://github.com/basho/riak_kv", {branch, "master"}}}, %% 这个模块依赖riak_core,在这一层里,封装了给各种client调用的接口,处理具体存储、M/R等。
{riak_search, "0.14.*", {git, "git://github.com/basho/riak_search",
{branch, "master"}}} %% 基于riak的全文检索实现
]}.

构建过程
通过rebar的reltool支持,在riak项目中,rebar.conf中定义了{sub_dirs,["rel"]},表示在rel目录下使用reltool创建一个发行版本。
在rel目录的rel.config中,{lib_dirs, ["../deps"]},定义了所有的子模块都放在了deps目录下。很长的一个config文件,有点像ant脚本。

函数规范定义:spec
-spec Module:Function(ArgType1, ..., ArgTypeN) -> ReturnType.
函数的参数数目必须与函数规范定义相同,否则编译出错。定义了type及spec,我们可以使用 dialyzer 对代码进行静态分析,在运行之前发现很多低级或者隐藏的错误。


riak源码阅读手记二 左右开弓 启动

 

 

riak源码阅读手记二 左右开弓 启动

erlang riak 54chen
目标系统(target system)
OTP系统定义里有这么一个东西:
可以被一般的erl脚本启动的系统叫基础目标系统;
除此之外还可以做运行时代码替换的系统叫简单目标系统;
如果还支持日志输出到文件、自动定时启动的话就叫做内嵌目标系统。

启动目标系统的方式
通过erlang/OTP标准的reltool工具生成的目标系统,可以用多种方式灵活启动。
第一种:

os> /usr/local/erl-target/bin/erl

这只启动了一个基础目标系统。基本没什么具体功能。

第二种:

os> /usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FIRST/start

用-boot参数,这可以启动一个简单目标系统。releases/RELEASES文件可用来做热替换。

第三种:

bin/start

这个脚本会去调用 bin/run_erl ,最终调用 bin/start_erl启动。run_erl是一个提供运行时日志输出到文件的封装。还提供了简单的机制attach到一个erlang shell。

自定义behaviour

-spec behaviour_info(atom()) -> 'undefined' | [{atom(), arity()}].
behaviour_info(callbacks) ->
[{start,2}, % (Partition, Config)
{stop,1}, % (State)
{get,2}, % (State, BKey)
{put,3}, % (State, BKey, Val)
{list,1}, % (State)
{list_bucket,2}, % (State, Bucket)
{delete,2}, % (State, BKey)
{drop,1}, % (State)
{fold,3}, % (State, Folder, Acc), Folder({B,K},V,Acc)
{is_empty,1}, % (State)
{callback,3}]; % (State, Ref, Msg) ->
behaviour_info(_Other) ->
undefined.

上述就是一个自定义的behaviour,使用的时候:

-behaviour(xxx).
...

有点类似java的interface.

riak源码阅读手记 运行安装

代码运行入口
riak-kv/ebin/riak_kv.app文件定义了otp标准项目的结构,一个不错的实例:http://www.iteye.com/topic/342819
{mod, {riak_kv_app, []}}一行定义了入口。打开riak_kv_app文件:
-export([start/2,stop/1]).
定义了两大个方法,start和stop。

先看start:
启动riak_kv及相关的server。
检查系统时间。
加入系统变量。
确保设置NWR的值和一些vclock的初始值。
看storage_backend是否启动。
在cluster_info中注册。
启动supervisor。
全部启动。

stop:application:stop。

跑一把试试:
A机:192.168.103.10
B机:192.168.97.48
C机:192.168.100.52
三个节点,已经装好erlang R13B04。
先在A机操作

wget http://downloads.basho.com/riak/riak-0.14/riak-0.14.2.tar.gz
tar zxvf riak-0.14.2.tar.gz
cd riak-0.14.2
make rel

然后在rel/riak目录下会有最编译好的节点程序。

scp -r rel root@192.168.100.52:/root/
scp -r rel root@192.168.97.48:/root/

cd rel/riak
ABC三机修改配置:
vim etc/app.config
把127.0.0.1修改为对应的ip
vim etc/vm.args
同上。

A:bin/riak start
B: bin/riak start
bin/riak-admin join riak@192.168.103.10
C: bin/riak start
bin/riak-admin join riak@192.168.103.10

./riak-admin status

欧了。

此时默认使用bitcask做为存储引擎。

riak源码阅读手记 与Cassandra相比

实现上:
1)虽然二者都是dynamo的实现,具体方法还是不一样的,riak更忠于dynamo的原文档,实现了所有文档提到的关键点。同时还增加了map reduce和links等功能。
2)Cassandra略去了一些文档里的关键点:向量时钟、按照key范围的大分区等。增加了一些方法如:范围查询、固定分区。

扩展:
1) riak提供了bin/riak join这样的命令来加入新的节点,基本完全按照dynamo文档所说的一样来实现了,从多个节点去获取原来的负载和数据回来,每个节点的压力都可以得到平衡。
2)相比之下,Cassandra集群的节点需要计算数据的一个范围。当加入节点时,Cassandra的策略是分出来相应分区上一半的范围去新节点。这点在一个Cassandra集群需要加节点时会很痛苦,可能会存在两个节点之间大规模的数据转移。

查询和分布:
1)riak有map reduce。
2)Cassandra可以接hadoop达到M/R的效果。

写冲突检查:
1)riak使用了向量时钟。
2)Cassandra使用了timestamp。如果时间有问题,可能会丢。

数据模型:
1)riak有bucket的概念,每个buckect可动态建立,每个buckect的数据模型都不一样。
2)Cassandra的keyspace与列簇都是依赖xml定义的,如果要修改,需要重启。

API:
1)riak提供了http与protocol buffers两种
2)Cassandra使用thrift

可配置的存储:
1)riak默认是bitcast存储,还有innodb,开发者很勤快,甚至还有leveldb。
2)Cassandra一直就是SSTable。

riak源码阅读手记 压力测试

基础环境:
三个台式机

一次操作:
操作一段购物车数据,先写包括3个货物的数据,然后取出来,再加上三个后存入。

压力结果:
1) 10个线程,无连接池化,每次新连接。PBClient。每次req包括上述一次操作里的一写一读一写三次。

Rate: 122 req/s
Rate: 103 req/s
Rate: 119 req/s
Rate: 110 req/s
Rate: 117 req/s
Rate: 116 req/s
Rate: 121 req/s
Rate: 110 req/s
Rate: 116 req/s
Rate: 111 req/s
Rate: 123 req/s
Rate: 122 req/s
Rate: 119 req/s
Rate: 123 req/s
Rate: 110 req/s

三个节点平均load为小于1。

2)50个线程,无连接池化,每次新连接。PBClient。每次req包括上述一次操作里的一写一读一写三次。

Rate: 124 req/s
Rate: 119 req/s
Rate: 124 req/s
Rate: 127 req/s
Rate: 114 req/s
Rate: 103 req/s
Rate: 93 req/s
Rate: 110 req/s
Rate: 120 req/s
Rate: 117 req/s
Rate: 121 req/s
Rate: 119 req/s
Rate: 109 req/s

三个节点平均load为1。接入节点load略高。

3)100个线程,无连接池化,每次新连接。PBClient。每次req包括上述一次操作里的一写一读一写三次。

Rate: 89 req/s
Rate: 109 req/s
Rate: 97 req/s
Rate: 108 req/s
Rate: 105 req/s
Rate: 105 req/s
Rate: 105 req/s
Rate: 106 req/s
Rate: 104 req/s
Rate: 106 req/s
Rate: 103 req/s
Rate: 91 req/s

三个节点平均load为1。接入节点load为大于2。

以上数据为从一个节点打入数据,接入节点负载略高。无池化,在建立连接浪费可能比较多。进行改进,合并发起连接的过程和接入节变成所有节点。

1)三个节点共同接入,最大连接数150,相当于池化连接,150个线程,PBClient。
Rate: 271 req/s
Rate: 275 req/s
Rate: 256 req/s
Rate: 276 req/s
Rate: 287 req/s
Rate: 288 req/s
Rate: 280 req/s
Rate: 293 req/s
Rate: 279 req/s
Rate: 291 req/s
Rate: 254 req/s
Rate: 287 req/s
Rate: 288 req/s
Rate: 283 req/s
Rate: 292 req/s

平均load 1,无明显负载偏移。

2)三个节点共同接入,最大连接数300,相当于池化连接,300个线程,PBClient。
Rate: 273 req/s
Rate: 234 req/s
Rate: 264 req/s
Rate: 264 req/s
Rate: 263 req/s
Rate: 277 req/s
Rate: 253 req/s
Rate: 250 req/s
Rate: 258 req/s
Rate: 218 req/s
Rate: 237 req/s
Rate: 268 req/s
Rate: 232 req/s
Rate: 245 req/s
Rate: 247 req/s

平均load 1.5,无明显负载偏移。

同机器的mysql性能压测结论为:http://www.54chen.com/java-ee/amoeba-benchmark-report.html
可得到比mysql qps高3倍以上(因为riak的压测中每req为2写1读)。

riak源码阅读手记 操作列表及supervisorTree一览

基于0.14.2的记录,1.0的变化会在后续记录。
riak
riak源码阅读手记一 初出茅庐 项目入口
http://www.54chen.com/_linux_/riak-source.html
riak源码阅读手记二 左右开弓 启动
http://www.54chen.com/_linux_/riak-cource-code.html
riak源码阅读手记 运行安装
http://www.54chen.com/_linux_/riak-source-install-run.html
一些常用的指令:
http://wiki.basho.com/Command-Line-Tools.html#riak-admin
riak源码阅读手记 压力测试
http://www.54chen.com/_linux_/riak-benchmark.html
riak源码阅读手记 操作列表及supervisorTree一览
http://www.54chen.com/_linux_/riak-source-notes-operation-supvisor-detail.html
[山寨收集操作列表]

看系统状况,有各种内存cpu硬盘的情况
bin/riak-admin status

节点更换新的ip地址:
如果是所有的节点都换,那在停下来集群,在每个节点都依次运行:
./riak-admin reip riak@192.168.103.9 riak@10.235.2.226
./riak-admin reip riak@192.168.97.48 riak@10.235.2.183
./riak-admin reip riak@192.168.100.52 riak@10.235.2.138

依次去对应的节点,修改etc:

  1. sed -i 's/192.168.103.9/10.235.2.226/g' app.config  
  2. sed -i 's/192.168.103.9/10.235.2.226/g' vm.args  
  3.   
  4. sed -i 's/192.168.97.48/10.235.2.183/g' app.config  
  5. sed -i 's/192.168.97.48/10.235.2.183/g' vm.args  
  6.   
  7. sed -i 's/192.168.100.52/10.235.2.138/g' app.config  
  8. sed -i 's/192.168.100.52/10.235.2.138/g' vm.args   

进入运行着的集群:
./riak attach
ctrl+d退出

看ring的分布情况:
>{ok,Ring} = riak_core_ring_manager:get_my_ring().

[看一点代码]
riak_kv_app -> riak_core->riak_core_sup[supervisor]->
riak_core_sup
|-riak_core_handoff_manager handoff管理 gen_server
|-riak_core_handoff_listener handoff接收 gen_nb_server
|-riak_core_ring_events 处理ring变化 gen_event
|-riak_core_ring_manager ring管理 gen_server2
|-riak_core_node_watcher_events 节点侦察 gen_event
|-riak_core_node_watcher 节点 gen_server
|-riak_core_gossip gossip协议 gen_server

[riak里的自定义behaviour]
-gen_nb_server from gen_server
-gen_server2 gen_server的一个拷贝 增加了pxxx的办法及增加了许多参数
-riak_core_vnode from gen_fsm
riak_kv:
-riak_kv_backend Riak backend behaviour

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值