Skip to content

Redis Codis

Redis Codis

[TOC]

Codis 简介

Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没有显著区别 (不支持的命令列表), 上层应用可以像使用单机的 Redis 一样使用, Codis 底层会处理请求的转发, 不停机的数据迁移等工作, 所有后边的一切事情, 对于前面的客户端来说是透明的, 可以简单的认为后边连接的是一个内存无限大的 Redis 服务。

Codis 3.x 组成部分:

  • Codis Server:基于 redis-3.2.8 分支开发。增加了额外的数据结构,以支持 slot 有关的操作以及数据迁移指令。具体的修改可以参考文档 redis 的修改
  • Codis Proxy:客户端连接的 Redis 代理服务, 实现了 Redis 协议。 除部分命令不支持以外(不支持的命令列表),表现的和原生的 Redis 没有区别(就像 Twemproxy)。
    • 对于同一个业务集群而言,可以同时部署多个 codis-proxy 实例;
    • 不同 codis-proxy 之间由 codis-dashboard 保证状态同步。
  • Codis Dashboard:集群管理工具,支持 codis-proxy、codis-server 的添加、删除,以及据迁移等操作。在集群状态发生改变时,codis-dashboard 维护集群下所有 codis-proxy 的状态的一致性。
    • 对于同一个业务集群而言,同一个时刻 codis-dashboard 只能有 0个或者1个;
    • 所有对集群的修改都必须通过 codis-dashboard 完成。
  • Codis Admin:集群管理的命令行工具。
    • 可用于控制 codis-proxy、codis-dashboard 状态以及访问外部存储。
  • Codis FE:集群管理界面。
    • 多个集群实例共享可以共享同一个前端展示页面;
    • 通过配置文件管理后端 codis-dashboard 列表,配置文件可自动更新。
  • Storage:为集群状态提供外部存储。
    • 提供 Namespace 概念,不同集群的会按照不同 product name 进行组织;
    • 目前仅提供了 Zookeeper、Etcd、Fs 三种实现,但是提供了抽象的 interface 可自行扩展。

codis的优缺点:

  • 优点:实现高并发读写,数据一致性高。
  • 缺点:性能有较大损耗,故障切换无法保证不丢key。无法进行读写分离。

codis 有以下特点:

  • 可以无缝迁移到codis,自带迁移工具
  • 可以动态扩容和缩容
  • 多业务完全透明,业务不知道运行的是codis
  • 支持多核心CPU,twemproxy只能单核
  • codis是中心基于proxy的设计,是客户端像连接单机一样操作proxy
  • 有部分命令不能支持,比如keys *等
  • 支持group划分,组内可以设置一个主多个从,通过sentinel 监控redis主从,当主down了自动将从切换为主
  • 设置的进程要最大等于CPU的核心,不能超过CPU的核心数
  • 其依赖于zookeeper,里面保存的key是redis主机位置,因此zookeeper要做高可用
  • 监控可以使用接口和dashboard

Codis 编译安装

  1. 安装 go 运行环境:
Terminal window
# 这里为了方便起见,我直接使用仓库进行安装
apt install -y golang
  1. 设置编译环境:

注意 $GOPATH 是本机所有第三方库 go 项目所在目录,Codis 仅是其中之一。

添加 $GOPATH/bin$PATH,例如:PATH=$PATH:$GOPATH/bin

编辑.profile文件,在行尾添加以下内容

Terminal window
export GOPATH=/home/codis/gopath
export PATH=$PATH:$GOPATH/bin

执行source .profile使其生效、

Terminal window
$ go env GOPATH
/home/codis/gopath
  1. 从官方仓库下载 Codis 的源码包:
Terminal window
mkdir -p $GOPATH/src/github.com/CodisLabs
cd $_ && git clone https://github.com/CodisLabs/codis.git -b release3.2
  1. 编译安装:
Terminal window
cd $GOPATH/src/github.com/CodisLabs/codis
make

编译安装完成之后,会在bin目录下生成以下文件:

Terminal window
$ ls bin/
assets codis-dashboard codis-ha codis-server redis-cli version
codis-admin codis-fe codis-proxy redis-benchmark redis-sentinel

:information_source:此外,可以直接从官方仓库下载对应的release包进行使用。

redis-codis 集群手动搭建

IP服务
172.16.1.128 & 172.16.1.134 & 172.16.1.138codis-server(主从)【3台】,codis-dashboard【1台】,codis-proxy【3台】,codis-fe【1台】
172.16.1.128 & 172.16.1.134 & 172.16.1.138zookeeper
  1. 编译安装 codis 参考上面的[Codis 编译安装](#Codis 编译安装)
  2. 编译安装 zk 参考 [zookeeper 部署安装](../../Zookeeper/Zookeeper Basic.md)

编辑zookeeper的配置文件zoo.conf,添加以下内容:

Terminal window
...
dataDir=/data/zookeeper
dataLogDir=/var/log/zookeeper
...
server.1=172.16.1.128:2888:3888
server.2=172.16.1.134:2888:3888
server.3=172.16.1.138:2888:3888

创建数据目录mkdir -p /data/zookeepermkdir -p /var/log/zookeeper

设置环境变量,在/etc/profile文件中添加以下内容:

Terminal window
export ZOOKEEPER_HOME=/usr/local/zookeeper
export PATH=$PATH:$ZOOKEEPER_HOME/bin

使之生效,source /etc/profile

创建myid文件,设置zookeeper的id,和server.ID对应,在dataDir指定的目录下 (即 /data/zookeeper目录) 创建名为 myid 的文件, 文件内容和 zoo.cfg 中当前机器的 id 一致:

Terminal window
# 在第1台zookeeper(172.16.1.128)上设置id=1
echo "1" >/data/zookeeper/myid
# 在第2台zookeeper(172.16.1.134)上设置id=2
echo "2" >/data/zookeeper/myid
# 在第3台zookeeper(172.16.1.138)上设置id=3
echo "3" >/data/zookeeper/myid

分别启动三台zk

Terminal window
[root@node02 conf]\# zkServer.sh start
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
...

查看 zk 集群状态:

Terminal window
[root@master zookeeper]\# zkServer.sh status
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower
[root@node01 ~]\# zkServer.sh status
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: leader
[root@node02 ~]\# zkServer.sh status
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower

…待续。。。

通过 ansible 快速部署集群

使用 ansible 可快速在单机、多机部署多套 codis 集群。 ansible 文件夹包含了部署 codis 集群的 playbook,根据自己部署环境修改 groups_var/all 文件里参数,修改 hosts 文件添加部署的环境 IP 即可。 ansible 安装也及其简单,各部署机器无需安装任何额外的 agent,彼此之间通过 ssh 通信。

git clone https://github.com/ansible/ansible.git -b stable-2.3
cd ./ansible
source ./hacking/env-setup
cd $codis_dir/ansible
ansible-playbook -i hosts site.yml

Docker 部署

Codis 3.x 起,开始正式支持 Docker 部署。这就需要 codis-dashboard 以及 codis-proxy 能够外部的 listen 地址暴露出来并保存在外部存储中。

  • codis-proxy 增加了 --host-admin 以及 --host-proxy 参数;
  • codis-dashboard 增加了 --host-admin 参数;

以 codis-proxy 的 Docker 为例:

$ docker run --name "Codis-Proxy" -d -p 29000:19000 -p 21080:11080 codis-image \
codis-proxy -c proxy.toml --host-admin 100.0.1.100:29000 --host-proxy 100.0.1.100:21080

codis-proxy 在启动后,会使用 --host-admin--host-proxy 参数所指定的实际地址替换 Docker 内监听的地址,向 codis-dashboard 注册。这样,例如使用 Jodis 的过程中,客户端就能够通过 100.0.1.100:29000 来访问 proxy 实例。

codis-dashboard 也是相同的道理,会使用 --host-admin 地址向外部存储注册,这样 codis-fe 也能通过该地址正确的对 codis-dashboard 进行操作。

具体样例可以参考 scripts/docker.sh

参考链接