一、riak_core基本原理
1. 基于dynamo设计的riak_core
通过某种hash算法,每份数据会对应着一个的整数。所有数据这样处理后就会映射到一个整数区间上。
对于riak_core,它管理着一个整数范围为[0-2^160]整数空间,这个空间形成一个首尾相连的环。
riak_core把这个环平均划分成多个分区partition(默认是64个分区),partition在环上的Token作为此partition的标识ID,每个partition交给一个或多个不同类型的vnode进程负责,每类vnode提供一套服务功能。partition的Token(或者说Index,Id)将作为对应vnode进程的id标识。如下图所示
多个partition可以挤在一个物理节点上。但是怎么挤是有严格要求的,我觉得看懂这个图的关键在于:每一种颜色代表同一个物理节点;各个颜色按照固定的顺序循环。这保证了任意两个相邻的partition肯定不在同一个物理节点上。因此Dynamo Preference List上的节点不会是同一个物理节点,也即一份数据的多份副本不会在同一个物理节点上了。(这里一个物理节点指一个erlang虚拟机,而不是一个实际的计算机)
riak_core的基本原理是,通过一致性hash算法,系统要处理的数据(例如,KV要存储的业务数据,或者要处理的用户请求会话)会被riak_core随机的均匀分布在ring上的各个分区中, 对每个数据的处理由该分区上的vnode进程负责。
由于hash算法的特点,当我们要对某个数据集进行处理时,这个数据集就会随机分布个不同的partition上,所以本质上是个数据并行的处理方式。
dynamo的简单介绍可以看这里: 论文重读: Amazon Dynamoriak官方介绍在这里。
2. riak_core的设计:partition和vnode
按照dynamo的设计思想,要处理的数据将会随机均匀的分布在dynamo ring上,riak_core进一步将这些数据又以partition为基本单元组织起来。对数据的处理将以partition为单元,通过vnode进程进行处理。数据的处理(或者叫服务)又有很多种,每类服务对应着一类vnode进程。
显然,partition是整个分布式系统并发、复制和容错的基本单元:以partition为单元进行数据并发处理;复制以partition为单元进行;容错也是如此:出错也以partition/vnode为单元出错。。。。
对于基于riak_core的分布式应用系统开发来说,vnode是重要的概念,简单的说,每个vnode进程负责一份partition上数据的处理,数据处理逻辑由用户负责实现。
一份partition可以有多个vnode进程管理,所以上图中a single partition/vnode应该是 a single partition with its assorted vnodes。
(用riak_core_node_watcher:services()可以察看应用系统中有哪些vnode服务)。
此外riak还有两类重要的服务:
riak的mapreduce基于riak_pipe实现,其vnode对应着riak_pipe_vnode模块。
riak还提供了二级索引搜索(riak_search)服务,其vnode对应着riak_search_vnode模块。
而一个实际的应用系统可能在功能上要比NoSQL数据库更多,它需要根据业务提供各种各样的服务,因此在vnode种类上就显得丰富多彩。比如rts实时日志统计这样一个例子就有两类vnode:riak_core_entry_vnode和riak_core_stat_vode,前者记录它负责的那份partition的所有数据,后者统计它负责的那份partition的所有数据。