1.1.1. 14.集群-Codis

简介

在大数据高并发场景下,单个 redis 实例性能往往捉襟见肘。

  1. 首先单个 redis 实例内存往往过大,导致 rdb 文件过大,会导致主从同步时,增量同步时间过长,实例重启恢复时间也更长。
  2. 其次 CPU 利用率上,单个 redis 实例只能利用单个 cpu 核心。单个核心处理海量数据和任务压力会非常大。

Codis 是由国人开发,与 redis-cluster 一样,去中心化。不过槽位没有 redis-cluster 分的精细。

Codis 示意图

Codis 是由 Go 语言开发。它是一个代理中间件 proxy。它和 redis 一样使用 redis 协议对外提供服务。当客户端向 Codis 发送一条指令时,Codis 负责将指令转发到后面的 redis 实例来执行,并将返回的结果转发回客户端。

客户端操纵 Codis 同 redis 几乎没有任何区别。

因为 Codis 是无状态的,它只是一个转发代理中间件,这表示可以启动多个 Codis 实例,每个实例都是对等的。多个实例可以增加整体 QPS。还能起到容灾效果,当一个 Codis 实例挂掉时,还有很多实例可以继续提供服务。

多个实例

Codis 分片原理

Codis 将所有 key 划分到 1024 个槽位(slot)上,它首先将客户端传过来的 key 进行 crc32 运算出 hash 值,然后用得到的值对 1024 进行取模,得到的余数为槽位。

分片原理

每个槽位后面对应多个 Redis 实例,Codis 会负责维护槽位和 Codis 之间的映射关系。

不同 Codis 实例间槽位关系如何同步

Codis 需要一个分布式配置存储数据库来专门持久化槽位关系。支持 zookeeper 和 etcd。

同步槽位关系

Codis 将槽位关系存储在 zookeeper 中,并提供了 Dashboard 用来观察和修改槽位关系。当槽位关系变化时,codis proxy 会监听到变化并同步槽位关系,从而时间多个 codis 实例共享槽位关系。

扩容

最开始 codis 只有一个 redis,所有的槽位都这个 redis,当增加 redis 实例后,槽位关系需要调整。需要将一半的槽位分给新的实例。

通过使用 slotsscan 指令,遍历所有的 key,然后挨个取出 key 放到新实例中。

在迁移过程中,codis 无法判断 key 在哪个实例中。当 Codis 发现 key 在正在迁移的槽中时,会强制先对当前 key 进行迁移,迁移完成后,再次请求新的实例。

scan 无法避免重复,但是并不影响迁移。因为单个 key 被迁移后,在旧实例中就被删除了,从而无法再被扫描出来。

自动均衡

Redis 新增实例,手动调整 slot 太繁琐。所以 codis 提供了自动均衡的功能,当系统比较空闲时,会观察每个 redis 实例的 slot 数量,如过不均衡,将启动自动均衡功能。

Codis 的代价

Codis 的 key 分散在不同实例中,所以不支持事务。 还有一些不支持的命令列表。 为了扩容,Codis 的单个 key 不能过大,否则迁移会卡顿。 Codis 集群配置中心使用 zk 实现,增加了 zk 运维的代价。

mget 指令的操作过程

mget 指令用于批量获取 key 的值,这些 key 可能分散到多个 key 中。Codis 的策略是,分别从每个实例中调用 mget 方法,然后再汇总返回给客户端。

mget 指令操作过程

Codis 的尴尬

Codis 不是官方项目,所以每次 Redis 官方更新后,Codis 都要看看自己少了什么。 Codis 总是比 官方慢一拍。

安装

# 安装 Go
$ sudo apt-get install golang

# 检测版本
$ go version
go version go1.10.2 linux/amd64

# 获取 go 安装地址
$ go env GOPATH
/home/vagrant/go

# 下载 codis 源码
$ mkdir -p $GOPATH/src/github.com/CodisLabs
$ cd $_ && git clone https://github.com/CodisLabs/codis.git -b release3.2

# 编译安装
$ cd $GOPATH/src/github.com/CodisLabs/codis
$ make

# 快速启动
$ ./admin/codis-dashboard-admin.sh start
$ ./admin/codis-proxy-admin.sh start
$ ./admin/codis-fe-admin.sh start

配置 codis 的 redis 实例,在 ./config 下创建 redis-codis-6481.conf,修改以下这些配置,还有一些多余的,通过命令行提示注释。

protected-mode no
port 6483
pidfile "/var/run/codis/redis-server-6483.pid"
logfile "/var/log/codis/redis-server-6483.log"
dbfilename "dump-6483.rdb"
dir "/var/lib/codis"

然后启动 codis 的 redis

$ sudo ./bin/codis-server ./config/redis-codis-6481.conf

接下来就在 fe 进行操作。fe 地址:127.0.0.1:9090。Homestead 需要打开 9090 端口。

参考

官网 Codis的安装与使用

Copyright © Kagami丶 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-12-10 20:25:25

results matching ""

    No results matching ""