以下内容是纯干货,看似比较复杂,其实更复杂!
数据系统其中一个典型的特点就是集群化,方便节点横向扩展,也就是所说的弹性扩容。之所以进行横向扩展,是因为纵向扩展难以处理庞大的数据量。将大数据进行切分,是实现数据集群化存储和计算的一种常用手段。
这个过程的学名叫做数据分片,将一个整体的数据划分到不同的节点去存储,然后通过路由来寻找到指定的节点,进行数据的读写操作。常用的数据分片方法有Hash分片和范围分片。而Hash分片包含所说的哈希取模法,一致性哈希以及虚拟桶算法。
本文,旨在从宏观层面,探讨Hash分片的三种方法。
1.哈希取模法
哈希取模法是最简单的一种哈希方法,其哈希函数无非就是mod,对于有k个成员的哈希算法即为:
H(key) = hash(key) mod K
这种方法比较容易实现,但是缺点就是不够灵活,当K的数量发生变化的时候,现有的集群就乱套了。
2.虚拟桶(virtual buckets)
虚拟桶方法是在索引key和存储节点之间放置一层中间的table,这个table就叫做虚拟桶。他的原理大致是这样的:
keys ---- vBuckets ----- node (server)
(1)在keys和vBuckts之间的映射关系是通过hash函数来实现的,一个虚拟桶可以容纳下多个key.
在代码实现上可以使用哈希取模法来映射到虚拟桶上,解决哈希冲突可以使用拉链法就搞定了。这样就可以实现一个桶对应多个key了
(2)在vBuckts和Node之间,是通过查询table的方式来实现的。
依然是多对一的关系,多个虚拟桶可以指向同一个物理节点。这一部分不是通过Hash函数来映射的,对应关系存储到table中,需要找到是路由到哪台节点上,可以通过查询表来找到,这个表是存储在内存中的,效率比较高。
这样做的好处就是,实现了索引key和存储节点之间映射关系的解耦,如果有新的节点增加神马的,只需要修改内存表就可以了,用不着修改哈希函数。
3.一致性哈希
一致性性哈希算法要比上述两种算法复杂得多,其核心技术是DHT,就是分布式哈希表,且一致性哈希算法也不唯一,在每台机器上存储一部分的哈希数据。
哈希空间是一个首尾相接的环状序列,把集群中的每台节点的IP和端口号通过哈希函数映射到这个收尾相接的环中,每个节点在环中的位置一定是唯一的。每个节点记录好他的前驱结点和后继结点,那么宏观上来看,这个数据结构就形成了环状。
每台节点存储这个环中从的一部分数据,例如从本节点到下一个节点这区间的数据归这个节点来存储。
在寻找数据的时候,请求客户端向这个分布式哈希集群中的任意一台节点请求数据,节点如果认为这条key在他的管辖范围内,就进行解析,如果不在他的范围内,就扔给自己的后继结点。
实际上,这只是一种最简单的情况,在实际中这样做效率比较差,还有一种叫做一致性哈希路由算法的东西,实现起来也比较复杂,一般也没有必要去自己实现。
实现一致性哈希算法的数据库例如著名的卡桑德拉(cassandra),此外实现虚拟桶的数据库,例如couthDB.通过数据的分片和路由,就可以比较easy地处理海量数据,在进行集群任务分配与协作的其他场合,当然也同样适用。如果自己造轮子,一般实现一个虚拟桶一般场景就搞定了,一致性哈希实现起来相对不太容易,不过可以扒现有的代码。
领取专属 10元无门槛券
私享最新 技术干货