欢迎来到HugNew-拥抱变化,扫一扫右边二维码关注微信订阅号:Martin说 或 加QQ群:427697041互相交流,Stay hungry, Stay foolish.

Codis集群的数据迁移及扩(缩)容

集群架构 Martin 4723℃ 0评论

上一篇文章codis集群搭建实践介绍了codis集群的搭建流程及测试,但是里面存在一个问题就是数据迁移及自由扩(缩)容,原因是由于采用原生的redis做codis-server所以不能使用codis的两个优势:数据迁移和Auto Rebalance。下面是摘自官方文档对这两个特性的解释:

数据迁移

安全和透明的数据迁移是 Codis 提供的一个重要的服务, 也是 Codis 区别于 Twemproxy 等静态的分布式 Redis 解决方案的地方.

数据迁移的最小单位是 key, 我们在 codis redis 中添加了一些指令, 实现基于key的迁移, 如 SLOTSMGRT等 (命令列表), 每次会将特定 slot 一个随机的 key 发送给另外一个 codis redis 实例, 这个命令会确认对方已经接收, 同时删除本地的这个 k-v 键值, 返回这个 slot 的剩余 key 的数量, 整个操作是原子的.

在 codis-config 管理工具中, 每次迁移任务的最小单位是 slot

如: 将slot id 为 [0-511] 的slot的数据, 迁移到 server group 2上, –delay 参数表示每迁移一个 key 后 sleep 的毫秒数, 默认是 0, 用于限速.

$ ../bin/codis-config slot migrate 0 511 2 --delay=10

迁移的过程对于上层业务来说是安全且透明的, 数据不会丢失, 上层不会中止服务.

注意, 迁移的过程中打断是可以的, 但是如果中断了一个正在迁移某个slot的任务, 下次需要先迁移掉正处于迁移状态的 slot, 否则无法继续 (即迁移程序会检查同一时刻只能有一个 slot 处于迁移状态).

Auto Rebalance

Codis 支持动态的根据实例内存, 自动对slot进行迁移, 以均衡数据分布.

$ ../bin/codis-config slot rebalance

要求:

  • 所有的codis-server都必须设置了maxmemory参数
  • 所有的 slots 都应该处于 online 状态, 即没有迁移任务正在执行
  • 所有 server group 都必须有 Master

现在我们对原来的方案修改,将原生的redis服务器切到codis-redis(codis-server 是 Codis 项目维护的一个 Redis 分支, 基于 2.8.13 开发, 加入了 slot 的支持和原子的数据迁移指令.)服务器,以便充分使用codis集群的优势,实现自动化运维。

1.检查本地是否安装原生的redis

如果本地已安装原生的redis,像上篇文章中已安装原生的redis服务器,先卸载删除。删除很简单,由于是源码包方式安装,执行rm命令直接删除安装目录即可。

2.安装codis及启动

上篇文章中已介绍了codis的安装流程(跟codis-proxy安装流程一样,到编译后复制完相关目录即可,这里不做过多介绍)。安装好codis后,修改配置文件,在/sample/redis_conf/目录下,有四个配置文件6380.conf、6381.conf、6382.conf、6383.conf,这几个配置文件跟原生redis配置文件redis.conf基本没区别,除了端口号和持久化方式。选择任意一个,这里选择6381.conf,执行命令cp 6381.conf 6379.conf复制并改名为6379.conf,vim打开配置文件,进行如下配置

daemonize yes

pidfile /var/run/redis_6379.pid

port 6379

logfile "/data/codis_server/logs/codis_6379.log"

save 900 1

save 300 10

save 60 10000

dbfilename 6379.rdb

dir /data/codis_server/data

配置完后修改下内核参数

echo "vm.overcommit_memory = 1" >>  /etc/sysctl.conf

sysctl -p

这里问什么要修改内核参数,大家都知道redis耗内存是很大的,如果不修改内核参数的话,在低内存环境下,会出现后台bgsave持久化数据失败(丢数据,这是很糟糕的)的情况,这跟redis的数据回写机制有关系。在Redis的数据回写机制分同步和异步两种:

  • 同步回写即SAVE命令,主进程直接向磁盘回写数据。在数据大的情况下会导致系统假死很长时间,所以一般不是推荐的。
  • 异步回写即BGSAVE命令,主进程fork后,复制自身并通过这个新的进程回写磁盘,回写结束后新进程自行关闭。由于这样做不需要主进程阻塞,系统不会假死,一般默认会采用这个方法。

个人感觉方法2采用fork主进程的方式很拙劣,但似乎是唯一的方法。内存中的热数据随时可能修改,要在磁盘上保存某个时间的内存镜像必须要冻结。冻结就会导致假死。fork一个新的进程之后等于复制了当时的一个内存镜像,这样主进程上就不需要冻结,只要子进程上操作就可以了。

在小内存的进程上做一个fork,不需要太多资源,但当这个进程的内存空间以G为单位时,fork就成为一件很恐怖的操作。何况在16G内存的主机上fork 14G内存的进程呢?肯定会报内存无法分配的。更可气的是,越是改动频繁的主机上fork也越频繁,fork操作本身的代价恐怕也不会比假死好多少。

所以需要直接修改/etc/sysctl.conf内核参数

vm.overcommit_memory= 1

sysctl -p

Linux内核会根据参数vm.overcommit_memory参数的设置决定是否放行。

  • 如果 overcommit_memory = 1,直接放行
  • overcommit_memory = 0:则比较 此次请求分配的虚拟内存大小和系统当前空闲的物理内存加上swap,决定是否放行。
  • overcommit_memory= 2:则会比较进程所有已分配的虚拟内存加上此次请求分配的虚拟内存和系统当前的空闲物理内存加上swap,决定是否放行。

修改完配置文件后,执行命令(启动命令跟redis一样,…./bin/codis-server …. /sample/redis_conf/6379.conf)启动codis-server服务。

3.删除zookeeper服务器相关的log及data文件

由于上篇文章中采用原生redis服务器通过codis.conf执行了很多操作,所以原来的zookeeper服务器会保存原来的操作的相关data,所以现在切到codis-server 需要把原来的相关数据删掉,重新在dashboard页面分配group和slot。进入zookeeper服务器,删掉datadir下相关的data及log即可。如果是正规流程安装的codis-server,则跳过这一步。

4.Migrate Slot

ok,后面dashboard分配group和slot的流程上篇已介绍,现在重点来说下在dashboard下如何进行数据迁移(扩容和缩容)和Auto Rebalance。现在假如只有两个group:group1(slot:0~511) 和group2(slot:512~1023),根据业务需要,现在需要给服务器扩容,这里添加新的group(group3),这就涉及到slot的重新分配 ,谈到slot的分配也就涉及到数据迁移操作(毕竟原来分配的slot上可能已存在数据),假如我打算将slot从800到1023分给新的group3,只需要在dashboard界面点击Migtate Slot按钮,在弹出的对话框分配slot即可,后台会自动进行slot的迁移。

migrate slot

后端迁移数据,对实际业务访问并不受影响,业务仍能正常使用正在迁移数据的group2,这点非常赞。

5.Auto Reblance

可能手动分配的slot并不合理对性能有影响,这里我们可以使用Auto Reblance自动均衡下slot分布,只要在dashboard界面点下Auto Reblance,后台会自动对slot进行迁移,迁移完后可以点击Slots Status查看slot的分布。

 

转载请注明:HugNew » Codis集群的数据迁移及扩(缩)容

喜欢 (3)or分享 (0)
发表我的评论
取消评论

表情