基于twemproxy+分布式ssdb的水平扩容方案实践分享

前言:

在存储方面,靠之前大容量单机存储已经不适合当前的企业需求,无论从成本,维护,可用性上都不是好的方案,所以分布式模式的存储系统应运而生,不过分布式也有分布式的代价,今天不讨论CAP,主要说说关于分布式模式下存储的水平扩容问题,如果是单一存储节点的话,扩容就是数据做整体复制到一个更大存储容量的节点上,但是分布式下可能是复制到一个普通的节点上,或者是从当前节点迁移到已经存在的另一个节点,保持负载均衡。话不概全,我从我们自己的解决方案给大家分享下心得,水平有限,轻拍^_^

本篇简单概述关于在twemproxy+分布式ssdb存储系统模式下关于存储服务水平扩容的方案

关于手动在线水平扩容的设计:

实现原理:

在用户请求过来的时候哦根据请求的key正常的做hashslot,但是需要判断此时是否正在有槽位迁移发生,如果有,需要判断我们的请求是否收到影响,所以从两方面着手:twemproxy,ssdb

twemproxy:

    作为双向代理,在后端ssdb发生槽位迁移的时候它需要负责用户的请求能不受该迁移操作的影响,当然性能上可能稍微有点损失的,这个后边说,twemproxy根据在zookpeer中记录的migrate_task信息判断初始化连接池中关于migrate的成员,同时注册监听该zk节点的父节点,以便在该操作迁移任务状态有变动后能及时收到通知,这块关于连接池的migrate信息更新启用多线程,如果在正常请求的时候发现我们要query的槽位正在发生迁移,那就需要"尝试"访问,大致过程是先访问选中的后端ssdb节点,如果请求OK那正常返回,本次请求平安结束,否则需要进行二次尝试,去迁移目的地进行访问,然后结束本次请求。这块的设计方案好处就是能避免因为操作迁移对请求的数据结果影响,但缺点是需要进行二次尝试,不过性能损失可以忽略的,多一次请求并不会增加太多的时间,例如get一次大概就是由10ms变为20ms

ssdb:

真正进行操作迁移的动作在此发生,不过在进入ssdb之前需要明确一个问题,就是我们所说的迁移的槽位其实是在twemproxy中记录的关于ssdb-server的sharding,算法使用的是hashslot,在ssdb-server中,它也有自己的0~16384槽位分布,但是我们在把key-value写入某一个ssdb-server的时候选用的槽位算法需要和twemproxy中选取后端ssdb-server的hashslot保持一致,假如不一致可能会出现数据迁移效果不好,例如A节点负责0-1号槽位,现在我们通过槽位迁移程序将0好槽位的数据迁移走,那在A节点上,其实可能存储的数据是散落在0~16383的,这样根本就不能做到迁移走0号槽位的所以数据,所以需要采用相同的槽位hashslot算法。

ssdb有个SSDBCluster的东西,以C-S的模式进行槽位迁移,C端就是migrate 的src,server端就是dst, cluster会分别启动client, server,然后给ssdb实例一个置migrating状态的信息,标识正在进行槽位迁移,其实迁移的本身很简单,就是简单的slot里的key-value迭代访问,然后以命令的形式发送到server端,其中为了防止在读写操作和槽位迁移发生冲突,每一个被迁移的key都会上锁,直到该key迁移完成,然后让cluster修改zk信息

具体的流程图:

基于twemproxy+分布式ssdb的水平扩容方案实践分享_第1张图片 ssdb槽位迁移流程简图

待解决问题:

其实现在手动迁移的方案还是不完善,首先例如在初始化的时候增加的node节点,有待商斛,应该移到最后槽位迁移完成来做,其次,在分布式系统中实现系统自治是很有必要的,这样的系统才更高效和稳定,每次的操作成本也更低,利于推广。

你可能感兴趣的:(分布式缓存&存储)