Codis安装并使用

简介

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

Codis架构
逻辑架构

访问层:访问方式可以是类似keepalived集群的vip方式,或者是通过java代码调用jodis控件再连接上zookeeper集群,然后查找到可用的proxy端,进而连接调用不同的codis-proxy地址来实现高可用的LVS和HA功能

代理层:中间层由codis-proxy和zookeeper处理数据走向和分配,通过crc32算法,把key平均分配在不同redis的某一个slot中.实现类似raid0的条带化,在旧版本的codis中,slot需要手工分配,在codis3.2之后,只要点一个按钮slot会自动分配,相当方便,但是也可以手动分配,需要另外调用codis-admin命令

数据层:最后codis-proxy把数据存进真实的redis-server主服务器上,由于codis的作者注重数据一致性,不允许有数据延时造成的数据不一致,所以架构从一开始就没考虑主从读写分离,从服务器仅仅是作为故障切换的冗余架构,由codis-dashboard监控各服务的状态,然后通过改写zookeeper数据和调用redis-sentinel实现故障切换功能

codis由四部分组成
codis-proxy 实现redis协议,由于本身是无状态的,因此可以部署很多个节点
codis-config 是codis的管理工具,包括添加/删除redis节点添加/删除proxy节点,发起数据迁移等操作,自带httpserver,支持管理后台方式管理配置
codis-server 是codis维护的redis分支,基于2.8.21分支,加入了slot的支持和原子的数据迁移指令; codis-proxy和codis-config只能和这个版本的redis交互才能正常运行
zookeeper 用于codis集群元数据的存储,维护codis集群节点
组件介绍
  • Codis Proxy:对外提供Redis服务,除了一些不支持的命令外(不支持的命令列表),表现的和原生的Redis没有区别。由于它是无状态的,所以我们可以部署多个节点,从而保证了可用性。
  • Codis Dashboard:集群管理工具,支持Codis Proxy的添加删除以及数据迁移等操作。对于一个Codis集群,Dashboard最多部署一个。
  • Codis Admin:集群管理的命令行工具。
  • Codis FE:集群管理界面,多个Codis集群可以共用一个Codis FE,通过配置文件管理后端的codis-dashboard。
  • Storage:为集群提供外部存储,目前支持ZooKeeper、Etcd、Fs三种。
  • Codis Server:基于3.2.8分支开发,增加额外的数据结构,用来支持slot有关的操作及数据迁移指令。
codis分片原理

现在我们已经知道了Codis会将指定key的Redis命令转发给下层的Redis。那么Codis如何知道某个key在哪个Redis上呢。

Codis采用Pre-sharding的技术来实现数据分片,默认分为1024个slot(0-1023)。Codis在接收到命令时,先对key进行crc32运算,然后再对1024取余,得到的结果就是对应的slot。然后就可以将命令转发给slot对应的Redis实例进行处理了。

安装配置

1.安装go运行环境:
Mac系统可以参考这个,其他系统可以参考这个教程

$ go version
go version go1.13.1 darwin/amd64

2.下载Codis源码
需要下载到指定目录:$GOPATH/src/github.com/CodisLabs

$ mkdir -p $GOPATH/src/github.com/CodisLabs
$ cd $GOPATH/src/github.com/CodisLabs
$ git clone https://github.com/CodisLabs/codis.git -b release3.2

3.编译源码
进入源码的codis目录,直接执行make命令即可。编译完成后,bin目录下的结构应该是这样的

$ ll bin 
total 192448
drwxr-xr-x  8 jokki  staff   256B 11 13 17:17 assets
-rwxr-xr-x  1 jokki  staff    17M 11 13 17:17 codis-admin
-rwxr-xr-x  1 jokki  staff    18M 11 13 17:16 codis-dashboard
-rw-r--r--  1 jokki  staff     5B 11 21 17:17 codis-dashboard.pid
-rwxr-xr-x  1 jokki  staff    16M 11 13 17:17 codis-fe
-rw-r--r--  1 jokki  staff     5B 11 21 17:17 codis-fe.pid
-rwxr-xr-x  1 jokki  staff    15M 11 13 17:17 codis-ha
-rwxr-xr-x  1 jokki  staff    19M 11 13 17:16 codis-proxy
-rw-r--r--  1 jokki  staff     5B 11 21 17:16 codis-proxy.pid
-rwxr-xr-x  1 jokki  staff   1.1M 11 13 17:16 codis-server
-rwxr-xr-x  1 jokki  staff    98K 11 13 17:16 redis-benchmark
-rwxr-xr-x  1 jokki  staff   161K 11 13 17:16 redis-cli
-rwxr-xr-x  1 jokki  staff   1.1M 11 13 17:16 redis-sentinel
-rw-r--r--  1 jokki  staff   170B 11 13 17:16 version
安装zookeeper

1.下载zookeeper
进入/usr/local目录(也可以安装在其他目录,这里我安装在根目录里面)
地址下载apache-zookeeper-3.5.9-bin.tar.gz

2.解压文件并重命名

sudo tar -zxvf apache-zookeeper-3.5.9-bin.tar.gz
sudo mv apache-zookeeper-3.5.9-bin/ zookeeper

3.在zookeeper 目录下新建两个文件夹 data 和 log,用于存储zookeeper的数据和日志

sudo mkdir data
sudo mkdir log

4.将conf目录下的zoo_sample.cfg文件更名为zoo.cfg,简单修改配置文件,自定义设置数据文件目录和日志文件目录

sudo mv zoo_sample.cfg zoo.cfg
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/Users/xxx/zookeeper/data
dataLogDir=/Users/xxx/zookeeper/log
# the port at which the clients will connect
clientPort=2181
#server.1=codis-1:2888:3888
#server.2=codis-2:2888:3888
#server.2=codis-3:2888:3888
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
"zoo.cfg" 29L, 975C

5.设置myid
设置myid在我们配置的dataDir指定的目录下面,创建一个myid文件,里面内容为一个数字,用来标识当前主机,conf/zoo.cfg文件配置的srver.X中的X为什么数字,则myid文件就输入这个数字,由于我只有一台zk,所以配置文件里可以不配置server.X,但还是要配置myid的,echo一个数字1进去即可。如果有多台zk,则分别在zk服务器上echo对应的数字进对应的myid文件

echo "1" > /Users/xxx/zookeeper/data/myid

5.启动zookeeper服务,zookeeper/bin目录下启动

$ ./zkServer.sh start
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /Users/xxxx/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

注:停止服务命令 ./zkServer.sh stop

$ ./zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /Users/xxxx/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: standalone

启动后会在那个目录下产生一个启动的日志zookeeper.out,查看这个日志可以查看是否正常启动了。由于单个zookeeper,所以这里指示Mode: standalone,如果有多个zk节点,就只有一个Mode: leader的状态,别的都是Mode: follower状态。

由于我现在是做一个机器做zk,所以这里几乎不用修改

$ cd /usr/local/codis
$ cat config.ini
zk=localhost:2181  //zookeeper的地址, 如果是zookeeper集群,可以这么写: zk=hostname1:2181,hostname2:2181,hostname3:2181,hostname4:2181,hostname5:2181,如果是etcd,则写成http://hostname1:port,http://hostname2:port,http://hostname3:port
product=test     //产品名称, 这个codis集群的名字, 可以认为是命名空间, 不同命名空间的codis没有交集
proxy_id=proxy_1  //proxy会读取, 用于标记proxy的名字, 针对多个proxy的情况, 可以使用不同的config.ini, 只需要更改 proxy_id 即可
net_timeout=5     //检测状态时间间隔
dashboard_addr=localhost:9090  //dashboard 服务的地址,CLI 的所有命令都依赖于 dashboard 的 RESTful API,所以必须启动
coordinator=zookeeper   //如果用etcd,则将zookeeper替换为etcd
[root@codis-1 bin]# 
配置说明

1.文件名可以任意,不是非得改为zoo.cfg
2.tickTime: zookeeper中使用的基本时间单位, 毫秒
3.dataDir: 内存数据快照的保存目录;如果没有自定义Log也使用该目录
4.clientPort: 监听Cli连接的端口号

到这里为止,我们的准备工作已经完成了。接下来我们启动测试集群。

启动顺序
1.zkServer.sh start    启动zookeeper服务
2.codis-dashboard-admin.sh start    启动 dashboard
3.codis-proxy-admin.sh start    启动proxy
4.codis-server-admin.sh start    启动server
5.codis-fe-admin.sh start    启动fe
打开web访问集群管理页面(fe地址:127.0.0.1:9090)设置集群
测试集群

1.启动codis-dashboard
进入admin目录,执行codis-dashboard-admin.sh脚本

$ ./codis-dashboard-admin.sh start
/Applications/MAMP/htdocs/GO/src/github.com/CodisLabs/codis/admin/../config/dashboard.toml
starting codis-dashboard ...

查看日志,观察是否启动成功

$ tail -100 ../log/codis-dashboard.log.2021-07-21
2021/07/21 17:24:32 topom.go:429: [WARN] admin start service on [::]:18080
2021/07/21 17:24:32 main.go:155: [WARN] option --pidfile = /Applications/MAMP/htdocs/GO/src/github.com/CodisLabs/codis/bin/codis-dashboard.pid
2021/07/21 17:24:32 fsclient.go:195: [INFO] fsclient - create /codis3/codis-demo/topom OK
2021/07/21 17:24:32 topom_sentinel.go:169: [WARN] rewatch sentinels = []
2021/07/21 17:24:32 main.go:179: [WARN] [0xc000178b40] dashboard is working ...

2.启动codis-proxy
执行codis-proxy-admin.sh脚本

$ ./codis-proxy-admin.sh start
/Applications/MAMP/htdocs/GO/src/github.com/CodisLabs/codis/admin/../config/proxy.toml
starting codis-proxy ...

查看是否启动成功

$ tail -100 ../log/codis-proxy.log.2021-07-21
2021/07/21 17:27:08 proxy_api.go:44: [WARN] [0xc0000f0840] API call /api/proxy/start/24c38f7765db81f837f0acbc2af8124a from 192.168.8.189:51250 []
2021/07/21 17:27:08 proxy_api.go:44: [WARN] [0xc0000f0840] API call /api/proxy/sentinels/24c38f7765db81f837f0acbc2af8124a from 192.168.8.189:51250 []
2021/07/21 17:27:08 proxy.go:293: [WARN] [0xc0000f0840] set sentinels = []
2021/07/21 17:27:08 main.go:343: [WARN] rpc online proxy seems OK
2021/07/21 17:27:09 main.go:233: [WARN] [0xc0000f0840] proxy is working ...

3.启动codis-server
执行codis-server-admin.sh脚本

$ ./codis-server-admin.sh start
/Applications/MAMP/htdocs/GO/src/github.com/CodisLabs/codis/admin/../config/redis.conf
starting codis-server ...

查看是否启动成功

$ tail -100 /tmp/redis_6379.log
1807:M 21 Jul 17:28:42.526 * Increased maximum number of open files to 10032 (it was originally set to 256).
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 3.2.11 (de1ad026/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 1807
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

1807:M 21 Jul 17:28:42.534 # Server started, Redis version 3.2.11
1807:M 21 Jul 17:28:42.534 * The server is now ready to accept connections on port 6379

注:如果执行报错,请先确认使用的用户是否有/tmp/redis_6379.log文件的读写权限。

4.启动codis-fe
执行codis-fe-admin.sh脚本

$ ./codis-fe-admin.sh start

starting codis-fe ...

查看是否启动成功

$ tail -100 ../log/codis-fe.log.2021-07-21
2021/07/21 17:34:31 main.go:101: [WARN] set ncpu = 4
2021/07/21 17:34:31 main.go:104: [WARN] set listen = 0.0.0.0:9090
2021/07/21 17:34:31 main.go:120: [WARN] set assets = /Applications/MAMP/htdocs/GO/src/github.com/CodisLabs/codis/bin/assets
2021/07/21 17:34:31 main.go:162: [WARN] set --filesystem = /tmp/codis
2021/07/21 17:34:31 main.go:216: [WARN] option --pidfile = /Applications/MAMP/htdocs/GO/src/github.com/CodisLabs/codis/bin/codis-fe.pid

全部启动成功之后,就可以访问http://127.0.0.1:9090,开始设置集群了。

image.png

在 Proxy 栏可看到我们已经启动的 Proxy,但是 Group 栏为空,因为我们启动的 codis-server 并未加入到集群
添加NEW GROUP,NEW GROUP 行输入 1,再点击 NEW GROUP 即可添加 Codis Server,Add Server 行输入我们刚刚启动的 codis-server 地址,添加到我们刚新建的 Group,然后再点击 Add Server 按钮即可


新增的集群 slot 状态是 offline,因此我们需要对它进行初始化(将 1024 个 slot 分配到各个 group),而初始化最快的方法可通过 fe 提供的 rebalance all slots 按钮来做,如下图所示,点击此按钮,我们即快速完成了一个集群的搭建;当然,也可以手动分配slot,比如,我们将group-1的10个slot分配给group-2,只需要点击Migrate Some按钮即可

到这里codis集群的搭建已经完毕

参考资料

https://github.com/wandoulabs/codis
https://blog.csdn.net/nawenqiang/article/details/84990508
https://zhuanlan.zhihu.com/p/69114539

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355

推荐阅读更多精彩内容