codis3.2 环境部署


下载codis3.2

https://objects.githubusercontent.com/github-production-release-asset-2e65be/25804514/2ab8d92e-053f-11e8-967e-3c733701c706?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20220316%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220316T034348Z&X-Amz-Expires=300&X-Amz-Signature=72d710fc55a3c57addea38c24f86658dbc0bd16759f4be27dca8b2b54aa025f8&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=25804514&response-content-disposition=attachment%3B%20filename%3Dcodis3.2.2-go1.9.2-linux.tar.gz&response-content-type=application%2Foctet-stream

Codis3.x有如下特点:

最新 release 版本为 codis-3.2,codis-server 基于 redis-3.2.8
支持 slot 同步迁移、异步迁移和并发迁移,对 key 大小无任何限制,迁移性能大幅度提升
相比 2.0:重构了整个集群组件通信方式,codis-proxy 与 zookeeper 实现了解耦,废弃了codis-config 等
元数据存储支持 etcd/zookeeper/filesystem 等,可自行扩展支持新的存储,集群正常运行期间,即便元存储故障也不再影响 codis 集群,大大提升 codis-proxy 稳定性
对 codis-proxy 进行了大量性能优化,通过控制GC频率、减少对象创建、内存预分配、引入 cgo、jemalloc 等,使其吞吐还是延迟,都已达到 codis 项目中最佳
proxy 实现 select 命令,支持多 DB
proxy 支持读写分离、优先读同 IP/同 DC 下副本功能
基于 redis-sentinel 实现主备自动切换
实现动态 pipeline 缓存区(减少内存分配以及所引起的 GC 问题)
proxy 支持通过 HTTP 请求实时获取 runtime metrics,便于监控、运维
支持通过 influxdb 和 statsd 采集 proxy metrics
slot auto rebalance 算法从 2.0 的基于 max memory policy 变更成基于 group 下 slot 数量
提供了更加友好的 dashboard 和 fe 界面,新增了很多按钮、跳转链接、错误状态等,有利于快速发现、处理集群故障
新增 SLOTSSCAN 指令,便于获取集群各个 slot 下的所有 key
codis-proxy 与 codis-dashbaord 支持 docker 部署

总体架构

Codis组件介绍

Codis Server:基于 redis-3.2.8 分支开发。增加了额外的数据结构,以支持 slot 有关的操作以及数据迁移指令。具体的修改可以参考文档 redis 的修改。
Codis Proxy:客户端连接的 Redis 代理服务, 实现了 Redis 协议。 除部分命令不支持以外(不支持的命令列表),表现的和原生的 Redis 没有区别(就像 Twemproxy)。
对于同一个业务集群而言,可以同时部署多个 codis-proxy 实例;
不同 codis-proxy 之间由 codis-dashboard 保证状态同步。
Redis sentinel:Redis官方推荐的高可用性(HA)解决方案。它可以实现对Redis的监控、通知、自动故障转移。如果Master不能工作,则会自动启动故障转移进程,将其中的一个Slave提升为Master,其他的Slave重新设置新的Master服务。
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、filesystem三种实现,但是提供了抽象的 interface 可自行扩展。

服务器资源规划

安装zookeeper 

 忽略 ,https://www.cnblogs.com/fengjian2016/p/14618788.html

配置go环境

下载go

https://dl.google.com/go/go1.9.2.linux-amd64.tar.gz

在/usr/local/路径下创建go目录,mkdir /usr/local/go,然后执行解压命令

tar -zxvf /home/go/go1.9.2.linux-amd64.tar.gz -C /usr/local/go

创建GO工作目录:mkdir $HOME/godir

配置环境变量,修改/etc/profile,添加如下语句:

#GO相关环境变量
export GOROOT=/usr/local/go
export GOPATH=$HOME/godir
export PATH=$PATH:$GOPATH/bin:$GOROOT/bin

安装Codis-dashboard

作用:集群管理工具,支持 codis-proxy、codis-server 的添加、删除,以及据迁移等操作。在集群状态发生改变时,codis-dashboard 维护集群下所有 codis-proxy 的状态的一致性。

1.对于同一个业务集群而言,同一个时刻 codis-dashboard 只能有 0个或者1个;
2.所有对集群的修改都必须通过 codis-dashboard 完成。

生成配置文件

[root@codis-dashboard tools]# tar -zcvf codis3.2.2-go1.9.2-linux.tar.gz 
[root@codis-dashboard tools]# cp codis3.2.2-go1.9.2-linux/codis-dashboard /usr/local/bin/
[root@codis-dashboard tools]# cp codis3.2.2-go1.9.2-linux/codis-admin /usr/local/bin/

[root@codis-dashboard tools]# mkdir /data/codis/config/ -p

[root@codis-dashboard tools]# cd /data/codis/config/
生成配置文件
[root@codis-dashboard config]# /usr/local/bin/codis-dashboard  --default-config | tee /data/codis/config/dashboard.conf
 
[root@codis-dashboard config]#cat  /data/codis/config/dashboard.conf

coordinator_name = "zookeeper"
coordinator_addr = "codis-proxy1:2181,codis-proxy2:2181,codis-proxy3:2181"
coordinator_auth = ""

product_name = "codis-superman"
product_auth = "123456"

admin_addr = "0.0.0.0:18080"

migration_method = "semi-async"
migration_parallel_slots = 100
migration_async_maxbulks = 200
migration_async_maxbytes = "32mb"
migration_async_numkeys = 500
migration_timeout = "30s"

sentinel_client_timeout = "10s"
sentinel_quorum = 2
sentinel_parallel_syncs = 1
sentinel_down_after = "30s"
sentinel_failover_timeout = "5m"
sentinel_notification_script = ""
sentinel_client_reconfig_script = ""

启动codis-dashboard

[root@codis-dashboard config]# nohup codis-dashboard --ncpu=1 --config=/data/codis/config/dashboard.conf  --log=/data/codis/logs/dashboard.log --log-level=WARN &
#--ncpu=24表示dashboard可以使用的CPU个数
#--config表示dashboard使用的配置文件

关闭codis-dashboard

[root@codis-dashboard ~]# codis-admin --dashboard=192.168.96.170:18080 --shutdown

安装Codis-proxy
作用:客户端连接的 Redis 代理服务, 实现了 Redis 协议。 除部分命令不支持以外(不支持的命令列表),表现的和原生的 Redis 没有区别(就像 Twemproxy)。
1.对于同一个业务集群而言,可以同时部署多个 codis-proxy 实例;
2.不同 codis-proxy 之间由 codis-dashboard 保证状态同步。

[root@codis-proxy1 tools]# cp codis3.2.2-go1.9.2-linux/codis-proxy  /usr/local/bin/

[root@codis-proxy1 tools]# mkdir /data/codis/config/ -p

生成配置文件

[root@codis-proxy1 config]# codis-proxy  --default-config | tee /data/codis/config/proxy.conf

修改配置文件

# Set Codis Product Name/Auth.
product_name = "codis-superman"  #设置项目名,与codis-dashboard相同
product_auth = "123456"  # 设置登录dashboard的密码(注意:与redis中requirepass一致)

# Set auth for client session
#   1. product_auth is used for auth validation among codis-dashboard,
#      codis-proxy and codis-server.
#   2. session_auth is different from product_auth, it requires clients
#      to issue AUTH  before processing any other commands.
session_auth = "superman123456"  # codis客户端通过codis-proxy登录密码

# Set bind address for admin(rpc), tcp only.
admin_addr = "0.0.0.0:11080"

# Set bind address for proxy, proto_type can be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
proto_type = "tcp4"
proxy_addr = "0.0.0.0:19000"

# Set jodis address & session timeout
#   1. jodis_name is short for jodis_coordinator_name, only accept "zookeeper" & "etcd".
#   2. jodis_addr is short for jodis_coordinator_addr
#   3. jodis_auth is short for jodis_coordinator_auth, for zookeeper/etcd, "user:password" is accepted.
#   4. proxy will be registered as node:
#        if jodis_compatible = true (not suggested):
#          /zk/codis/db_{PRODUCT_NAME}/proxy-{HASHID} (compatible with Codis2.0)
#        or else
#          /jodis/{PRODUCT_NAME}/proxy-{HASHID}
jodis_name = "zookeeper"
jodis_addr = "codis-proxy1:2181,codis-proxy2:2181,codis-proxy3:2181"
jodis_auth = ""
jodis_timeout = "20s"
jodis_compatible = false

# Set session recv buffer size & timeout.
session_recv_timeout = "0s" #如果不为0可能导致应用程序出现”write: broken pipe”的问题

启动codis-proxy

nohup codis-proxy --ncpu=1 --config=/data/codis/config/proxy.conf --log=/data/codis/logs/proxy.log --log-level=WARN &

程序codis-proxy启动后,仍然处于waiting状态,虽然侦听了proxy_addr端口,但是不会accept连接请求。只有将codis-proxy加入到集群并完成集群状态的同步,才能将状态改为online。最终才能accept连接请求。

安装Codis-fe

作用:集群管理界面。
1.多个集群实例共享可以共享同一个前端展示页面;
2.通过配置文件管理后端codis-dashboard列表,配置文件可自动更新。

[root@codis-fe config]# cp /data/tools/codis3.2.2-go1.9.2-linux/codis-fe /usr/local/bin/
[root@codis-fe config]# cp /data/tools/codis3.2.2-go1.9.2-linux/codis-admin /usr/local/bin/

生成配置配置文件

[root@codis-fe config]# codis-admin --dashboard-list --zookeeper=codis-proxy1:2181 | tee /data/codis/config/codis-fe.json

查看

[root@codis-fe config]# cat /data/codis/config/codis-fe.json 
[
    {
        "name": "codis-superman",
        "dashboard": "codis-dashboard:18080"
    }
]

拷贝codis-fe 静态文件

[root@codis-fe config]# mv /data/tools/codis3.2.2-go1.9.2-linux/assets/ /data/codis/config/

启动codis-fe

nohup codis-fe --ncpu=1 --log=/data/codis/logs/fe.log --log-level=WARN --dashboard-list=/data/codis/config/codis-fe.json --listen=0.0.0.0:80 & 

使用Codis-fe的WEB界面配置集群

添加codis-server

找到Group菜单栏,首先输入group ID,并点击New Group按钮,就可以新建一个group。

然后在下面输入redis-server的地址与端口,以及要加入哪个Group,点击Add Server按钮即可。

每个group加入的第一个server将成为主节点,其他server会作为从节点。为了防止出现单点问题,主从节点建议按照类似下图中的交错方式来分配。

server加入完毕后,点击上面绿色的Replica(s): Enable All按钮,就可以启用所有主从配置。

配置sentinel

初始化slot分配
Codis预置了1024个数据分片(即slot),通过crc32(key) % 1024的规则确定数据应该被放在哪个slot中。每个slot的数据都有且仅有一个codis-group来持有。

集群创建时,所有slot都处于Offline状态。我们可以手动指定哪些slot分配到哪些group上,但如果是第一次安装,最简单的方法就是直接点击下面的“Rebalance All Slots”按钮,等待所有slot从Migrating变成Default状态,Codis就自动将slot分配好了。

性能测试


用自带的redis-benchmark来压测性能,模拟500个并发和100万个请求.注意区分好登录的地址和端口,还有密码
压测codis-proxy的性能

/usr/local/codis/bin/redis-benchmark -h codis-proxy1 -p 19000 -a "superman123456" -c 500 -n 1000000 -q


压测单节点的性能

/usr/local/codis/bin/redis-benchmark -h redis1 -p 6379 -a "123456" -c 500 -n 1000000 -q



redis-benchmark参数解析:
-h ip地址
-p redis端口
-a 认证密码
-c 设定多少个并发连接
-n 总共多少个请求
-q 显示模式:简要模式

测试结果示例:

参考:https://blog.csdn.net/nazeniwaresakini/article/details/104220249
https://blog.csdn.net/screamPY/article/details/103136027

报错解决

{
    "Cause": "ERR unknown command 'SLOTSINFO'",
    "Stack": [
        {
            "Name": "github.com/CodisLabs/codis/pkg/utils/redis.(*Client).Do",
            "File": "/home/travis/gopath/src/github.com/CodisLabs/codis/pkg/utils/redis/client.go",
            "Line": 58
        },
        {
            "Name": "github.com/CodisLabs/codis/pkg/utils/redis.(*Client).SlotsInfo",
            "File": "/home/travis/gopath/src/github.com/CodisLabs/codis/pkg/utils/redis/client.go",
            "Line": 250
        },
        {
            "Name": "github.com/CodisLabs/codis/pkg/topom.(*apiServer).GroupAddServer",
            "File": "/home/travis/gopath/src/github.com/CodisLabs/codis/pkg/topom/topom_api.go",
            "Line": 375
        },
        {
            "Name": "github.com/CodisLabs/codis/pkg/topom.(*apiServer).GroupAddServer-fm",
            "File": "/home/travis/gopath/src/github.com/CodisLabs/codis/pkg/topom/topom_api.go",
            "Line": 91
        }
    ]
}

codis-server 是打过 patch 的 redis。为了支持 slot 迁移以及异步迁移。而你用的是官方的 redis,所以不支持。

codis-dashboard 以及 codis-server 强制关机后, lock

sentinel_client_reconfig_script = ""
2022/03/18 16:02:30 zkclient.go:23: [INFO] zookeeper - Connected to 192.168.96.168:2181
2022/03/18 16:02:30 zkclient.go:23: [INFO] zookeeper - Authenticated: id=144116480260964354, timeout=60000
2022/03/18 16:02:30 zkclient.go:23: [INFO] zookeeper - Re-submitting `0` credentials after reconnect
2022/03/18 16:02:30 topom.go:189: [ERROR] store: acquire lock of codis-superman failed
[error]: zk: node already exists
    6   /home/travis/gopath/src/github.com/CodisLabs/codis/pkg/models/zk/zkclient.go:247
            github.com/CodisLabs/codis/pkg/models/zk.(*Client).create
    5   /home/travis/gopath/src/github.com/CodisLabs/codis/pkg/models/zk/zkclient.go:196
            github.com/CodisLabs/codis/pkg/models/zk.(*Client).Create.func1
    4   /home/travis/gopath/src/github.com/CodisLabs/codis/pkg/models/zk/zkclient.go:129
            github.com/CodisLabs/codis/pkg/models/zk.(*Client).shell
    3   /home/travis/gopath/src/github.com/CodisLabs/codis/pkg/models/zk/zkclient.go:195
            github.com/CodisLabs/codis/pkg/models/zk.(*Client).Create
    2   /home/travis/gopath/src/github.com/CodisLabs/codis/pkg/models/store.go:119
            github.com/CodisLabs/codis/pkg/models.(*Store).Acquire
    1   /home/travis/gopath/src/github.com/CodisLabs/codis/pkg/topom/topom.go:188
            github.com/CodisLabs/codis/pkg/topom.(*Topom).Start
    0   /home/travis/gopath/src/github.com/CodisLabs/codis/cmd/dashboard/main.go:169
            main.main

解决办法
 codis-admin --remove-lock --product=codis-superman --zookeeper=192.168.96.168:2181