Riak源码阅读手记 压力测试

erlang 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源码阅读手记 与Cassandra相比

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 实现上: 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源码阅读手记 运行安装

riak riak源码阅读手记一 初出茅庐 项目入口 http://www.54chen.com/_linux_/riak-source.html

riak源码阅读手记二 左右开弓 启动 http://www.54chen.com/_linux_/riak-cource-code.html

代码运行入口 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做为存储引擎。

淘宝分布式数据库系统OceanBase观后闲话小记

http://code.taobao.org/trac/OceanBase/wiki/intro
讲得还比较细。

数据模型: oceanBase采用类似cassandra的tablet/sstable数据模型实现,简单说就是bigtable的数据模型。

系统目标: 其目标比较明确,是一个强CA类系统,P(分区能力)。目标是强一致性、高可用性,分区能力稍弱。从文档上看,他们并不担心的快速的数据增长量。

去中心化: 见图: taobao oceanbase RootServer/UpdateServer是一个中心节点,这个有死翘翘的可能性(好吧,他们搞了一主一备)。

支持的作: 基础的merge/join都可以,一般使用上是够用了。DDL DML的定义基本上是还需要发展的。另外如果开源出来了,广泛项目使用意义上,还需要支持UDF user defined function,实际上把mysql文档实现一遍就ok了。

继续观望,欢迎抛砖。向开源的项目致敬。

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

简介 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 对代码进行静态分析,在运行之前发现很多低级或者隐藏的错误。