Linux的企业-Codis 3集群搭建详解

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云原生网关 MSE Higress,422元/月
简介:

Codis 3集群搭建详解

Codis 3介绍

对于Redis集群方案有好多种,基本常用的就是twemproxy,codis、redis cluster这三种解决方案,本人有幸工作中都大量使用过,各有利有弊,下面这篇文章详解讲解一下豌豆尖的Codis 3。由于业务中还使用有Codis 2,所以对于Codis 2也写了一篇文章Codis 2集群搭建。Codis总体来说还算不错,仅供大家学习和参考。

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

Codis 3集群搭建详解

Codis 3.x由以下组件组成:

Codis Server:基于 redis-2.8.21 分支开发。增加了额外的数据结构,以支持 slot 有关的操作以及数据迁移指令。具体的修改可以参考文档 redis 的修改。

Codis Proxy:客户端连接的Redis代理服务, 实现了Redis协议。 除部分命令不支持以外(不支持的命令列表),表现的和原生的Redis没有区别(就像Twemproxy)。

o 对于同一个业务集群而言,可以同时部署多个codis-proxy实例;

o 不同codis-proxy之间由codis-dashboard保证状态同步。

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

o 对于同一个业务集群而言,同一个时刻 codis-dashboard 只能有 0个或者1个;

o 所有对集群的修改都必须通过 codis-dashboard 完成。

Codis Admin:集群管理的命令行工具。

o 可用于控制codis-proxy、codis-dashboard状态以及访问外部存储。

Codis FE:集群管理界面。

o 多个集群实例共享可以共享同一个前端展示页面;

o 通过配置文件管理后端codis-dashboard列表,配置文件可自动更新。

Codis HA:为集群提供高可用。

o 依赖codis-dashboard实例,自动抓取集群各个组件的状态;

o 会根据当前集群状态自动生成主从切换策略,并在需要时通过codis-dashboard完成主从切换。

Storage:为集群状态提供外部存储。

o 提供Namespace概念,不同集群的会按照不同product name进行组织;

o 目前仅提供了Zookeeper和Etcd两种实现,但是提供了抽象的interface可自行扩展。

安装配置Codis 3集群

此次试验服务部署架构方式如下:

10.0.60.152           10.0.60.153            10.0.60.154 zookeeper             zookeeper              zookeeper codis-proxy           codis-proxy            codis-proxy codis-dashboard       codis-dashboard(备)    codis-dashboard(备) redis(master)         redis(master)          redis(slave) codis-fe              codis-fe(备)           redis(slave)

1

2

3

4

5

6

10.0.60.152           10.0.60.153            10.0.60.154

zookeeper             zookeeper              zookeeper

codis-proxy           codis-proxy            codis-proxy

codis-dashboard       codis-dashboard(备)    codis-dashboard(备)

redis(master)         redis(master)          redis(slave)

codis-fe              codis-fe(备)           redis(slave)

此次试验用到的软件及版本如下:

system:CentOS 6/7版本

Jdk:1.8版本

Zookeeper:3.4版本(http://zookeeper.apache.org/releases.html)

Go:go1.5.2.Linux-amd64.tar.gz版本(https://golang.org/doc/install?download=go1.5.2.linux-amd64.tar.gz)

Codis:3.0.3版本(https://github.com/CodisLabs/codis/archive/3.0.3.zip)

安装参考文档:https://github.com/CodisLabs/codis/blob/release3.0/doc/tutorial_zh.md

1、安装配置zookeeper

Zookeeper分布式服务框架,是Apache Hadoop的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。Codis依赖zookeeper才能协同工作。

首先安装开发工具及openjdk,zookeeper是由Java语言开发的,所以需要openjdk环境。

$ yum groupinstall "Development tools" "Compatibility libraries" -y $ yum install openssl-devel openssl -y $ yum install java-1.8.0-openjdk-devel java-1.8.0-openjdk -y

1

2

3

$yum groupinstall"Development tools""Compatibility libraries"-y

$yum install openssl-devel openssl-y

$yum install java-1.8.0-openjdk-devel java-1.8.0-openjdk-y

确定Java运行环境正常

$ java -version openjdk version "1.8.0_101" OpenJDK Runtime Environment (build 1.8.0_101-b13) OpenJDK 64-Bit Server VM (build 25.101-b13, mixed mode)

1

2

3

4

$java-version

openjdk version"1.8.0_101"

OpenJDK Runtime Environment(build1.8.0_101-b13)

OpenJDK64-Bit Server VM(build25.101-b13,mixed mode)

安装二进制版本的zookeeper

$ tar xvf zookeeper-3.4.9.tar.gz -C /usr/local/ $ ln -s /usr/localzookeeper-3.4.9/ /usr/local/zookeeper $ cd /usr/local/zookeeper/conf $ cp zoo_sample.cfg zoo.cfg

1

2

3

4

$tar xvf zookeeper-3.4.9.tar.gz-C/usr/local/

$ln-s/usr/localzookeeper-3.4.9//usr/local/zookeeper

$cd /usr/local/zookeeper/conf

$cpzoo_sample.cfgzoo.cfg

编译zookeeper配置文件/usr/local/zookeeper/conf/zoo.cfg

maxClientCnxns=60 tickTime=2000 initLimit=10 syncLimit=5 dataDir=/data/zookeeper/db dataLogDir=/data/zookeeper/log clientPort=2181 # cluster configure server.1=10.0.60.152:2888:3888 server.2=10.0.60.153:2888:3888 server.3=10.0.60.154:2888:3888

1

2

3

4

5

6

7

8

9

10

11

maxClientCnxns=60

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/data/zookeeper/db

dataLogDir=/data/zookeeper/log

clientPort=2181

# cluster configure

server.1=10.0.60.152:2888:3888

server.2=10.0.60.153:2888:3888

server.3=10.0.60.154:2888:3888

$ mkdir /data/zookeeper/{db,log} -p

1

$mkdir/data/zookeeper/{db,log}-p

其中2888表示zookeeper程序监听端口,3888表示zookeeper选举通信端口。

下面需要生成ID,这里需要注意,myid对应的zoo.cfg的server.ID,比如第二台zookeeper主机对应的myid应该是2,以此类推,三个主机分别为:

10.0.60.152$ echo 1 > /data/zookeeper/db/myid 10.0.60.153$ echo 2 > /data/zookeeper/db/myid 10.0.60.154$ echo 3 > /data/zookeeper/db/myid

1

2

3

10.0.60.152$echo1>/data/zookeeper/db/myid

10.0.60.153$echo2>/data/zookeeper/db/myid

10.0.60.154$echo3>/data/zookeeper/db/myid

然后输出环境变量。

$ export PATH=$PATH:/usr/local/zookeeper/bin/ $ source /etc/profile

1

2

$export PATH=$PATH:/usr/local/zookeeper/bin/

$source/etc/profile

然后就可以启动zookeeper了。

$ zkServer.sh start

1

$zkServer.shstart

查看各个zookeeper节点的状态(会有一个leader节点,两个follower节点)。

[root@node1 ~]# zkServer.sh status Mode: follower [root@node2 ~]# zkServer.sh status Mode: leader [root@node3 ~]# zkServer.sh status Mode: follower

1

2

3

4

5

6

[root@node1~]# zkServer.sh status

Mode:follower

[root@node2~]# zkServer.sh status

Mode:leader

[root@node3~]# zkServer.sh status

Mode:follower

客户端连接,可以查看相关信息。

$ zkCli.sh -server 127.0.0.1:2181

1

$zkCli.sh-server127.0.0.1:2181

至此,zookeeper已经搞定了。

2、go安装(codis是go语言写的,所以这些机器需要安装go环境)

首先下载go二进制安装包

https://golang.org/doc/install?download=go1.5.2.linux-amd64.tar.gz

官方界面介绍了如何安装GO运环境,对于GO运行环境来说,有一些特定的GOROOT和GOPATH环境变量需要设置,这是必须的,不然无法运行go程序。这里最好安装go1.5.2版本,不然后面编译Codis有些小问题。

$ tar xvf go1.5.2.linux-amd64.tar.gz -C /usr/local

1

$tar xvf go1.5.2.linux-amd64.tar.gz-C/usr/local

解压完成后,GO就安装完了,下面设置一个GOPATH目录,其实就是go程序运行目录。

$ mkdir /usr/local/codis

1

$mkdir/usr/local/codis

然后就可以设置GO需要的环境变量,路径看好,千万别搞错了。

$ cat /etc/profile.d/go.sh #!/bin/bash # export GOROOT=/usr/local/go export GOPATH=/usr/local/codis/ export PATH=$PATH:$GOROOT/bin

1

2

3

4

5

6

$cat/etc/profile.d/go.sh

#!/bin/bash

#

export GOROOT=/usr/local/go

export GOPATH=/usr/local/codis/

export PATH=$PATH:$GOROOT/bin

应用一下go.sh

$ chmod a+x /etc/profile.d/go.sh $ source /etc/profile.d/go.sh

1

2

$chmoda+x/etc/profile.d/go.sh

$source/etc/profile.d/go.sh

查看GO版本

$ go version go version go1.5.2 linux/amd64

1

2

$go version

go version go1.5.2linux/amd64

3、安装godep

Codis的编译使用了godep,如果没有安装的话就会报godep command not found的错误,godep是golang的一个包管理工具,类似于Python的pip。

$ mkdir -p $GOPATH/src/github.com/tools $ cd $GOPATH/src/github.com/tools $ go get -u github.com/tools/godep $ cd godep $ go install ./

1

2

3

4

5

$mkdir-p$GOPATH/src/github.com/tools

$cd$GOPATH/src/github.com/tools

$go get-ugithub.com/tools/godep

$cdgodep

$go install./

其中go install ./命令会将godep执行程序生成到$GOPATH/bin下。

$ ll $GOPATH/bin -rwxr-xr-x. 1 root root 10329080 Oct 11 11:00 godep

1

2

$ll$GOPATH/bin

-rwxr-xr-x.1root root10329080Oct1111:00godep

然后将$GOPATH/bin加到/etc/profile.d/go.sh中,主要是引用godep命令:

$ cat /etc/profile.d/go.sh #!/bin/bash # export GOROOT=/usr/local/go export GOPATH=/usr/local/codis/ export PATH=$PATH:$GOROOT/bin export PATH=$GOROOT/bin:$GOPATH/bin:$PATH

1

2

3

4

5

6

7

$cat/etc/profile.d/go.sh

#!/bin/bash

#

export GOROOT=/usr/local/go

export GOPATH=/usr/local/codis/

export PATH=$PATH:$GOROOT/bin

export PATH=$GOROOT/bin:$GOPATH/bin:$PATH

$ source /etc/profile.d/go.sh

1

$source/etc/profile.d/go.sh

查看godep效果

$ which godep /usr/local/codis/bin/godep $ godep version godep v74 (linux/amd64/go1.5.2)

1

2

3

4

$which godep

/usr/local/codis/bin/godep

$godep version

godep v74(linux/amd64/go1.5.2)

4、下载并编译安装codis 3

$ cd /root $ wget https://github.com/CodisLabs/codis/archive/3.0.3.zip $ unzip 3.0.3.zip $ mkdir /usr/local/codis/src/github.com/CodisLabs $ cp -fr ./codis-3.0.3/ /usr/local/codis/src/github.com/CodisLabs/codis $ cd /usr/local/codis/src/github.com/CodisLabs/codis $ make

1

2

3

4

5

6

7

$cd/root

$wget https://github.com/CodisLabs/codis/archive/3.0.3.zip

$unzip3.0.3.zip

$mkdir/usr/local/codis/src/github.com/CodisLabs

$cp-fr./codis-3.0.3//usr/local/codis/src/github.com/CodisLabs/codis

$cd/usr/local/codis/src/github.com/CodisLabs/codis

$make

编译完成后,查看一下Codis产生的文件。

$ ll total 52 drwxr-xr-x. 3 root root 4096 Oct 11 11:08 bin drwxr-xr-x. 7 root root 4096 Oct 11 11:05 cmd drwxr-xr-x. 5 root root 4096 Oct 11 11:05 doc -rw-r--r--. 1 root root 338 Oct 11 11:05 Dockerfile drwxr-xr-x. 5 root root 4096 Oct 11 11:05 extern drwxr-xr-x. 3 root root 4096 Oct 11 11:06 Godeps -rw-r--r--. 1 root root 1352 Oct 11 11:05 Makefile -rw-r--r--. 1 root root 1076 Oct 11 11:05 MIT-LICENSE.txt drwxr-xr-x. 6 root root 4096 Oct 11 11:05 pkg -rw-r--r--. 1 root root 2966 Oct 11 11:05 README.md drwxr-xr-x. 2 root root 4096 Oct 11 11:05 scripts -rwxr-xr-x. 1 root root 418 Oct 11 11:05 version -rw-r--r--. 1 root root 1081 Oct 11 11:05 wandoujia_license.txt

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

$ll

total52

drwxr-xr-x.3root root4096Oct1111:08bin

drwxr-xr-x.7root root4096Oct1111:05cmd

drwxr-xr-x.5root root4096Oct1111:05doc

-rw-r--r--.1root root338Oct1111:05Dockerfile

drwxr-xr-x.5root root4096Oct1111:05extern

drwxr-xr-x.3root root4096Oct1111:06Godeps

-rw-r--r--.1root root1352Oct1111:05Makefile

-rw-r--r--.1root root1076Oct1111:05MIT-LICENSE.txt

drwxr-xr-x.6root root4096Oct1111:05pkg

-rw-r--r--.1root root2966Oct1111:05README.md

drwxr-xr-x.2root root4096Oct1111:05scripts

-rwxr-xr-x.1root root418Oct1111:05version

-rw-r--r--.1root root1081Oct1111:05wandoujia_license.txt

在bin文件夹内生成codis-admin、codis-dashboard、codis-fe、codis-ha、codis-proxy、 codis-server六个可执行文件。另外, bin/assets文件夹是codis-dashboard http服务需要的前端资源, 需要和codis-dashboard放置在同一文件夹下。

输出Codis执行文件,添加最后一行PATH变量。

$ cat /etc/profile.d/go.sh #!/bin/bash # export GOROOT=/usr/local/go export GOPATH=/usr/local/codis/ export PATH=$PATH:$GOROOT/bin export PATH=$GOROOT/bin:$GOPATH/bin:$PATH export PATH=$PATH:/usr/local/codis/src/github.com/CodisLabs/codis/bin/

1

2

3

4

5

6

7

8

$cat/etc/profile.d/go.sh

#!/bin/bash

#

export GOROOT=/usr/local/go

export GOPATH=/usr/local/codis/

export PATH=$PATH:$GOROOT/bin

export PATH=$GOROOT/bin:$GOPATH/bin:$PATH

export PATH=$PATH:/usr/local/codis/src/github.com/CodisLabs/codis/bin/

$ source /etc/profile.d/go.sh

1

$source/etc/profile.d/go.sh

至此,Codis安装完成。但需要注意的是,如果你是用golang 1.5 beta3以上的版本进行编译,还有可能出现的一个问题是:

GOPATH=godep path godep restore Error: GO15VENDOREXPERIMENT is enabled and the vendor/ directory is not a valid Go workspace. godep: Error restore requires GOPATH but it is empty. make: *** [godep] Error 1

1

2

3

4

GOPATH=godep path godep restore

Error:GO15VENDOREXPERIMENT isenabled andthe vendor/directory isnotavalid Go workspace.

godep:Error restore requires GOPATH but it isempty.

make:***[godep]Error1

这是因为golang 1.5 beta3之后go添加了GO15VENDOREXPERIMENT这个特性,并在1.6版本就默认开启,你可以参照Codis issue715里面的方案解决。最简单就是在编译前

export GO15VENDOREXPERIMENT=0

1

export GO15VENDOREXPERIMENT=0

5、为Codis创建标准目录

Codis安装完成后,就可以为Codis创建一些标准的目录,用来存储Codis的脚本目录、配置文件目录、日志目录、PID目录、Redis配置目录等。

$ mkdir -p /data/codis/sh $ mkdir -p /data/codis/conf $ mkdir -p /data/codis/log $ mkdir -p /data/codis/run $ mkdir -p /data/codis/redis/bin $ mkdir -p /data/codis/redis/redis-6379 $ mkdir -p /data/codis/redis/redis-6380

1

2

3

4

5

6

7

$mkdir-p/data/codis/sh

$mkdir-p/data/codis/conf

$mkdir-p/data/codis/log

$mkdir-p/data/codis/run

$mkdir-p/data/codis/redis/bin

$mkdir-p/data/codis/redis/redis-6379

$mkdir-p/data/codis/redis/redis-6380

复制Codis自带的redis-2.8.21相关工具到标准目录中。

$ cd /usr/local/codis/src/github.com/CodisLabs/codis/extern/redis-2.8.21/src/ $ cp ./{redis-benchmark,redis-cli,redis-sentinel,redis-server} /data/codis/redis/bin/

1

2

$cd/usr/local/codis/src/github.com/CodisLabs/codis/extern/redis-2.8.21/src/

$cp./{redis-benchmark,redis-cli,redis-sentinel,redis-server}/data/codis/redis/bin/

添加环境变量

$ cat /etc/profile.d/go.sh #!/bin/bash # export GOROOT=/usr/local/go export GOPATH=/usr/local/codis/ export PATH=$PATH:$GOROOT/bin export PATH=$GOROOT/bin:$GOPATH/bin:$PATH export PATH=$PATH:/usr/local/codis/src/github.com/CodisLabs/codis/bin/ export PATH=$PATH:/data/codis/redis/bin

1

2

3

4

5

6

7

8

9

$cat/etc/profile.d/go.sh

#!/bin/bash

#

export GOROOT=/usr/local/go

export GOPATH=/usr/local/codis/

export PATH=$PATH:$GOROOT/bin

export PATH=$GOROOT/bin:$GOPATH/bin:$PATH

export PATH=$PATH:/usr/local/codis/src/github.com/CodisLabs/codis/bin/

export PATH=$PATH:/data/codis/redis/bin

$ source /etc/profile.d/go.sh

1

$source/etc/profile.d/go.sh

6、配置启动Codis各组件—-启动Redis

考虑到性能,主库关闭aof和rdp,从库只开启aof即可。下面这份配置就是生产环境中的配置,具体的含义可以看本博客的Redis生产环境配置文件详解章节。

主库:/data/codis/redis/redis-6379/redis.conf

###基本参数### daemonize yes pidfile /data/codis/run/redis-6379.pid port 6379 tcp-backlog 65535 bind 0.0.0.0 timeout 0 tcp-keepalive 0 loglevel notice logfile "/data/codis/log/redis-6379.log" databases 16 lua-time-limit 5000 maxclients 10000 ###慢日志参数### slowlog-log-slower-than 10000 slowlog-max-len 128 ###内存参数### maxmemory 3G maxmemory-policy noeviction ###RDB持久化参数### #save 3600 1 #stop-writes-on-bgsave-error yes #rdbcompression yes #rdbchecksum yes #dbfilename dump.rdb ###AOF持久化参数### #no-appendfsync-on-rewrite yes #appendonly yes #appendfilename "appendonly.aof" #appendfsync no #auto-aof-rewrite-min-size 512mb #auto-aof-rewrite-percentage 100 #aof-load-truncated yes #aof-rewrite-incremental-fsync yes ###客户端Buffer参数### client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 ###其他参数### hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-entries 512 list-max-ziplist-value 64 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 activerehashing yes latency-monitor-threshold 0 ###安全参数### #requirepass  123456789

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

###基本参数###

daemonize yes

pidfile/data/codis/run/redis-6379.pid

port6379

tcp-backlog65535

bind0.0.0.0

timeout0

tcp-keepalive0

loglevel notice

logfile"/data/codis/log/redis-6379.log"

databases16

lua-time-limit5000

maxclients10000

 

###慢日志参数###

slowlog-log-slower-than10000

slowlog-max-len128

 

###内存参数###

maxmemory3G

maxmemory-policy noeviction

 

###RDB持久化参数###

#save 3600 1

#stop-writes-on-bgsave-error yes

#rdbcompression yes

#rdbchecksum yes

#dbfilename dump.rdb

 

###AOF持久化参数###

#no-appendfsync-on-rewrite yes

#appendonly yes

#appendfilename "appendonly.aof"

#appendfsync no

#auto-aof-rewrite-min-size 512mb

#auto-aof-rewrite-percentage 100

#aof-load-truncated yes

#aof-rewrite-incremental-fsync yes

 

###客户端Buffer参数###

client-output-buffer-limit normal000

client-output-buffer-limit slave256mb64mb60

client-output-buffer-limit pubsub32mb8mb60

 

###其他参数###

hash-max-ziplist-entries512

hash-max-ziplist-value64

list-max-ziplist-entries512

list-max-ziplist-value64

set-max-intset-entries512

zset-max-ziplist-entries128

zset-max-ziplist-value64

hll-sparse-max-bytes3000

activerehashing yes

latency-monitor-threshold0

 

###安全参数###

#requirepass  123456789

从库:/data/codis/redis/redis-6380/redis.conf

###基本参数### daemonize yes pidfile /data/codis/run/redis-6380.pid port 6380 tcp-backlog 65535 bind 0.0.0.0 timeout 0 tcp-keepalive 0 loglevel notice logfile "/data/codis/log/redis-6380.log" databases 16 lua-time-limit 5000 maxclients 10000 ###慢日志参数### slowlog-log-slower-than 10000 slowlog-max-len 128 ###内存参数### maxmemory 3G maxmemory-policy noeviction ###RDB持久化参数### #save 3600 1 #stop-writes-on-bgsave-error yes #rdbcompression yes #rdbchecksum yes #dbfilename dump.rdb ###AOF持久化参数### no-appendfsync-on-rewrite yes appendonly yes appendfilename "appendonly.aof" appendfsync no auto-aof-rewrite-min-size 512mb auto-aof-rewrite-percentage 100 aof-load-truncated yes aof-rewrite-incremental-fsync yes ###客户端Buffer参数### client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 ###其他参数### hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-entries 512 list-max-ziplist-value 64 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 activerehashing yes latency-monitor-threshold 0 ###安全参数### #requirepass  123456789

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

###基本参数###

daemonize yes

pidfile/data/codis/run/redis-6380.pid

port6380

tcp-backlog65535

bind0.0.0.0

timeout0

tcp-keepalive0

loglevel notice

logfile"/data/codis/log/redis-6380.log"

databases16

lua-time-limit5000

maxclients10000

 

###慢日志参数###

slowlog-log-slower-than10000

slowlog-max-len128

 

###内存参数###

maxmemory3G

maxmemory-policy noeviction

 

###RDB持久化参数###

#save 3600 1

#stop-writes-on-bgsave-error yes

#rdbcompression yes

#rdbchecksum yes

#dbfilename dump.rdb

 

###AOF持久化参数###

no-appendfsync-on-rewrite yes

appendonly yes

appendfilename"appendonly.aof"

appendfsync no

auto-aof-rewrite-min-size512mb

auto-aof-rewrite-percentage100

aof-load-truncated yes

aof-rewrite-incremental-fsync yes

 

###客户端Buffer参数###

client-output-buffer-limit normal000

client-output-buffer-limit slave256mb64mb60

client-output-buffer-limit pubsub32mb8mb60

 

###其他参数###

hash-max-ziplist-entries512

hash-max-ziplist-value64

list-max-ziplist-entries512

list-max-ziplist-value64

set-max-intset-entries512

zset-max-ziplist-entries128

zset-max-ziplist-value64

hll-sparse-max-bytes3000

activerehashing yes

latency-monitor-threshold0

 

###安全参数###

#requirepass  123456789

可以使用codis-server启动redis了。

$ codis-server /data/codis/redis/redis-6379/redis.conf $ codis-server /data/codis/redis/redis-6380/redis.conf

1

2

$codis-server/data/codis/redis/redis-6379/redis.conf

$codis-server/data/codis/redis/redis-6380/redis.conf

7、配置启动Codis各组件—-启动dashboard(集群中某一个节点)

首先生成默认的配置文件:

$ codis-dashboard --default-config | tee /data/codis/conf/dashboard.toml

1

$codis-dashboard--default-config|tee/data/codis/conf/dashboard.toml

修改配置文件参数如下:

# Set Coordinator, only accept "zookeeper" & "etcd" coordinator_name = "zookeeper" coordinator_addr = "10.0.60.152:2181,10.0.60.153:2181,10.0.60.154:2181" # Set Codis Product {Name/Auth}. product_name = "codis-demo" product_auth = "" # Set bind address for admin(rpc), tcp only. admin_addr = "0.0.0.0:18080"

1

2

3

4

5

6

7

8

9

10

# Set Coordinator, only accept "zookeeper" & "etcd"

coordinator_name="zookeeper"

coordinator_addr="10.0.60.152:2181,10.0.60.153:2181,10.0.60.154:2181"

 

# Set Codis Product {Name/Auth}.

product_name="codis-demo"

product_auth=""

 

# Set bind address for admin(rpc), tcp only.

admin_addr="0.0.0.0:18080"

配置文件参数说明:

coordinator_name:外部存储类型,接受zookeeper/etcd,这里我们使用的zookeeper集群。

coordinator_addr:外部存储地址。

product_name:集群名称,满足正则\w[\w\.\-]*。

product_auth:集群密码,默认为空。

admin_addr:RESTful API端口。

启动dashboard

$ nohup codis-dashboard --ncpu=2 --config=/data/codis/conf/dashboard.toml --log=/data/codis/log/dashboard.log --log-level=WARN &

1

$nohupcodis-dashboard--ncpu=2--config=/data/codis/conf/dashboard.toml--log=/data/codis/log/dashboard.log--log-level=WARN&

参数解释:

–ncpu=N:最大使用CPU个数。

-c CONF, –config=CONF:指定启动配置文件。

-l FILE, –log=FILE:设置log输出文件。

–log-level=LEVEL:设置log输出等级:INFO,WARN,DEBUG,ERROR,默认INFO,推荐WARN。

PS:dashboard只需要在一个节点启动即可,启动时会向zookeeper注册信息(topom),如果有其他节点也启动 dashboard时,向zookeeper注册信息发现里面有信息时,就会无法启动的。另外,如果dashboard异常退出,请看后面的异常处理案 例。

8、配置启动Codis各组件—-启动codis-proxy(集群中所有节点)

首先生成默认的配置文件:

$ codis-proxy --default-config | tee /data/codis/conf/proxy.toml

1

$codis-proxy--default-config|tee/data/codis/conf/proxy.toml

修改配置文件参数如下:

product_name = "codis-demo" product_auth = "" admin_addr = "0.0.0.0:11080" proto_type = "tcp4" proxy_addr = "0.0.0.0:19000" jodis_addr = "10.0.60.152:2181,10.0.60.153:2181,10.0.60.154:2181" jodis_timeout = 10 backend_ping_period = 5 session_max_timeout = 1800 session_max_bufsize = 131072 session_max_pipeline = 1024 session_keepalive_period = 60

1

2

3

4

5

6

7

8

9

10

11

12

product_name="codis-demo"

product_auth=""

admin_addr="0.0.0.0:11080"

proto_type="tcp4"

proxy_addr="0.0.0.0:19000"

jodis_addr="10.0.60.152:2181,10.0.60.153:2181,10.0.60.154:2181"

jodis_timeout=10

backend_ping_period=5

session_max_timeout=1800

session_max_bufsize=131072

session_max_pipeline=1024

session_keepalive_period=60

配置文件参数介绍:

product_name:产品名称, 这个codis集群的名字, 可以认为是命名空间, 不同命名空间的codis没有交集。

product_auth:集群密码,默认为空。Codis 3.x支持AUTH,但是要求所有组件使用的AUTH必须完全相同。

admin_addr:RESTful API端口。

proto_type:Redis端口类型,接受tcp/tcp4/tcp6/unix/unixpacket。

proxy_addr:Redis端口地址或者路径。

jodis_addr:Jodis注册zookeeper地址。

jodis_timeout:Jodis注册session timeout时间,单位second。

backend_ping_period:与codis-server探活周期,单位second,0表示禁止。

session_max_timeout:与client连接最大读超时,单位second,0表示禁止。

session_max_bufsize:与client连接读写缓冲区大小,单位byte。

session_max_pipeline:与client连接最大的pipeline大小。

session_keepalive_period:与client的tcp keepalive周期,仅tcp有效,0表示禁止。

启动codis-proxy

$ nohup codis-proxy --ncpu=2 --config=/data/codis/conf/proxy.toml --log=/data/codis/log/proxy.log --log-level=WARN &

1

$nohupcodis-proxy--ncpu=2--config=/data/codis/conf/proxy.toml--log=/data/codis/log/proxy.log--log-level=WARN&

–ncpu=N:最大使用CPU个数。

-c CONF, –config=CONF:指定启动配置文件。

-l FILE, –log=FILE:设置log输出文件。

–log-level=LEVEL:设置log输出等级:INFO,WARN,DEBUG,ERROR;默认INFO,推荐WARN。

–ulimit=NLIMIT:检查ulimit -n的结果,确保运行时最大文件描述不少于NLIMIT。

codis-proxy启动后,处于waiting状态,监听proxy_addr地址,但是不会accept连接,添加到集群并完成集群状态的同步,才能改变状态为online。添加的方法有以下两种:

第一种:通过codis-fe添加,通过Add Proxy按钮,将admin_addr加入到集群中,如下图(具体操作要等到后面codis-fe启动后才可以):

Codis 3集群搭建详解

第二种:通过codis-admin命令行工具添加,方法如下(添加3个proxy):

$ codis-admin --dashboard=10.0.60.152:18080 --create-proxy -x 10.0.60.152:11080 $ codis-admin --dashboard=10.0.60.152:18080 --create-proxy -x 10.0.60.153:11080 $ codis-admin --dashboard=10.0.60.152:18080 --create-proxy -x 10.0.60.154:11080

1

2

3

$codis-admin--dashboard=10.0.60.152:18080--create-proxy-x10.0.60.152:11080

$codis-admin--dashboard=10.0.60.152:18080--create-proxy-x10.0.60.153:11080

$codis-admin--dashboard=10.0.60.152:18080--create-proxy-x10.0.60.154:11080

其中–dashboard需要指定codis-dashboard的管理地址,–create-proxy指定为和codis-proxy的admin_addr地址,。添加过程中,codis-dashboard会完成如下一系列动作:

1)获取proxy信息,对集群name以及auth进行验证,并将其信息写入到外部存储中;

2)同步slots状态;

3)标记proxy状态为online,此后proxy开始accept连接并开始提供服务;

PS:在添加codis-proxy的时候需要特别注意,这个地方容易出现各种问题,最好能一次性添加成功,不然就需要删除zookeeper数据了,然后重新开始。还有一点需要注意的是,测试中发现一旦删除掉某个proxy后,再次添加就会报错。

9、配置启动Codis各组件—-启动codis-fe(可选组件)

首先生成默认的配置文件,配置文件codis.json可以手动编辑,也可以通过codis-admin从外部存储(这里是zookeeper)中拉取,如下操作:

$ codis-admin --dashboard-list --zookeeper=127.0.0.1:2181 | tee /data/codis/conf/codis.json

1

$codis-admin--dashboard-list--zookeeper=127.0.0.1:2181|tee/data/codis/conf/codis.json

拉去的配置文件信息:

$ cat /data/codis/conf/codis.json [    {        "name": "codis-demo",        "dashboard": "10.0.60.152:18080"    } ]

1

2

3

4

5

6

7

$cat/data/codis/conf/codis.json

[

    {

        "name":"codis-demo",

        "dashboard":"10.0.60.152:18080"

    }

]

启动codis-fe,注意启动codis-fe的时候,必须要使用codis-fe的全路径进行启动,因为codis-fe需要找到前端静态文 件,也就是要找到/usr/local/codis/src/github.com/CodisLabs/codis/bin/assets目录。

$ nohup `which codis-fe` --ncpu=2 --log=/data/codis/log/fe.log --log-level=WARN --dashboard-list=/data/codis/conf/codis.json \ --listen=0.0.0.0:8080 &

1

2

$nohup`which codis-fe`--ncpu=2--log=/data/codis/log/fe.log--log-level=WARN--dashboard-list=/data/codis/conf/codis.json\

--listen=0.0.0.0:8080&

web监控端口是801端口,我们可以在浏览器打开http://10.0.60.152:8080看看图形化界面。

10、添加Redis Server Group(在集群中一台服务器上操作即可,也可以在面板图形界面操作)

首先使用codis-admin工具创建组,按照上面的规划的,我们创建2个组即可:

$ codis-admin --dashboard=10.0.60.152:18080 --create-group --gid=1 $ codis-admin --dashboard=10.0.60.152:18080 --create-group --gid=2

1

2

$codis-admin--dashboard=10.0.60.152:18080--create-group--gid=1

$codis-admin--dashboard=10.0.60.152:18080--create-group--gid=2

然后使用codis-admin工具给组添加Redis主机(2个主机为一个组):

$ codis-admin --dashboard=10.0.60.152:18080 --group-add --gid=1 --addr=10.0.60.152:6379 $ codis-admin --dashboard=10.0.60.152:18080 --group-add --gid=1 --addr=10.0.60.154:6379

1

2

$codis-admin--dashboard=10.0.60.152:18080--group-add--gid=1--addr=10.0.60.152:6379

$codis-admin--dashboard=10.0.60.152:18080--group-add--gid=1--addr=10.0.60.154:6379

$ codis-admin --dashboard=10.0.60.152:18080 --group-add --gid=2 --addr=10.0.60.153:6380 $ codis-admin --dashboard=10.0.60.152:18080 --group-add --gid=2 --addr=10.0.60.154:6380

1

2

$codis-admin--dashboard=10.0.60.152:18080--group-add--gid=2--addr=10.0.60.153:6380

$codis-admin--dashboard=10.0.60.152:18080--group-add--gid=2--addr=10.0.60.154:6380

把从库跟主库同步:

$ codis-admin --dashboard=10.0.60.152:18080 --sync-action --create --addr=10.0.60.154:6379 $ codis-admin --dashboard=10.0.60.152:18080 --sync-action --create --addr=10.0.60.154:6380

1

2

$codis-admin--dashboard=10.0.60.152:18080--sync-action--create--addr=10.0.60.154:6379

$codis-admin--dashboard=10.0.60.152:18080--sync-action--create--addr=10.0.60.154:6380

需要注意的是如果当从库运行一段时间后挂掉了,那么重新启动后需要人为手动地将主从进行同步,执行上面的命令即可,或者图形界面操作(反之,如果主库挂了,马上又好了,这时候从库会自动重新连接上的,不需要人为干预)。

若slave需要提升为master,操作如下:

$ codis-admin --dashboard=10.0.60.152:18080 --promote-server --gid=1 --addr=10.0.60.154:6379

1

$codis-admin--dashboard=10.0.60.152:18080--promote-server--gid=1--addr=10.0.60.154:6379

注意的是,当从库提升为主库后,那么原来的主库就会掉线,如果想把它作为现在主库的从库,还是需要人为干预的,因为这个涉及到数据安全性的问题。

11、初始化slots并设置server group服务的slot 范围(在集群中一台服务器上操作即可,也可以在面板图形界面操作)

Codis采用Pre-sharding的技术来实现数据的分片, 默认分成1024个slots (0-1023),对于每个key来说,通过以下公式确定所属的Slot Id : SlotId = crc32(key) %1024。每一个slot都会有一个且必须有一个特定的server group id来表示这个slot的数据由哪个server group来提供。

$ codis-admin --dashboard=10.0.60.152:18080 --slot-action --create-range --beg=0 --end=511 --gid=1 $ codis-admin --dashboard=10.0.60.152:18080 --slot-action --create-range --beg=512 --end=1023 --gid=2

1

2

$codis-admin--dashboard=10.0.60.152:18080--slot-action--create-range--beg=0--end=511--gid=1

$codis-admin--dashboard=10.0.60.152:18080--slot-action--create-range--beg=512--end=1023--gid=2

至此,一个简单的集群就搭建完成了。但是此时redis虽然能够很好地进行切换了。但是是需要人为切换,如果想做到自动切换,那么还需要Codis的另一个组件codis-ha。

12、配置启动Codis各组件—-启动codis-ha(可选组件)

codis-ha --log=/data/codis/log/ha.log --log-level=WARN --interval=3 --dashboard=127.0.0.1:18080 &

1

codis-ha--log=/data/codis/log/ha.log--log-level=WARN--interval=3--dashboard=127.0.0.1:18080&

工作原理:

注意:Codis HA工具仅仅是Codis集群HA的一部分,单独工作能力有限。

默认以5s(–interval是调整时间间隔的)为周期,codis-ha会从codis-dashboard中拉取集群状态,并进行主从切换;

codis-ha在以下状态下会退出:

1、从codis-dashboard获取集群状态失败时;

2、向codis-dashboard发送主从切换指令失败时;

codis-ha在以下状态下不会进行主从切换:

1、存在proxy状态异常:

因为提升主从需要得到所有proxy的确认,因此必须确保操作时所有proxy都能正常响应操作指令;

2、网络原因造成的master异常:

若存在slave满足slave.master_link_status == up,通常可以认为master并没有真的退出,而是由于网络原因或者响应延迟造成的master状态获取失败,此时codis-ha不会对该group进行操作;

3、没有满足条件的slave时:

提升过程会选择满足slave.master_link_status == down,并且slave.master_link_down_since_seconds最小的进行操作。这就要求被选择的slave至少在过去一段时 间内与master是成功同步状态,这个时间间隔是2d+5,其中d是codis-ha检查周期默认5秒。

注意:因此,应用codis-ha时还需要结合对codis-proxy和codis-server的可用性监控,否则codis-ha无法保证可靠性。

PS:当codis-ha启动后,你可以测试关掉redis master,看看redis slave是否马上会成为主节点。

最后来看一下配置完成后的web界面是什么样子?

Codis 3集群搭建详解

在此界面中也可以进行,组创建、将redis加入到组、删除redis主机、设置主从同步、将从节点提升为主节点、初始化slot等等。并且还可以看见OPS、内存、key等性能情况。另外可以在web界面进行slot迁移的操作,具体可以自行多试验试验。

13、测试Codis

连接codis-proxy代理端口即可,然后操作redis命令。

$ redis-cli -h 10.0.60.152 -p 19000 127.0.0.1:19000> set k1 v1 OK

1

2

3

$redis-cli-h10.0.60.152-p19000

127.0.0.1:19000>set k1 v1

OK

Zookeeper相关操作

查看zk中codis产品:

$ zkCli.sh -server 127.0.0.1:2181 [zk: 127.0.0.1:2181(CONNECTED) 1] ls /codis3/codis-demo/ proxy   slots   topom   group

1

2

3

$zkCli.sh-server127.0.0.1:2181

[zk:127.0.0.1:2181(CONNECTED)1]ls/codis3/codis-demo/

proxy slots topom group

查看zk中的dashboard信息:

[zk: 127.0.0.1:2181(CONNECTED) 2] get /codis3/codis-demo/topom {    "start_time": "2016-10-13 18:09:21.802793218 +0800 CST",    "admin_addr": "10.0.60.152:18080",    "product_name": "codis-demo",    "pid": 3386,    "pwd": "/usr/local/codis/src/github.com/CodisLabs/codis/extern/redis-2.8.21/src",    "sys": "Linux" }

1

2

3

4

5

6

7

8

9

[zk:127.0.0.1:2181(CONNECTED)2]get/codis3/codis-demo/topom

{

    "start_time":"2016-10-13 18:09:21.802793218 +0800 CST",

    "admin_addr":"10.0.60.152:18080",

    "product_name":"codis-demo",

    "pid":3386,

    "pwd":"/usr/local/codis/src/github.com/CodisLabs/codis/extern/redis-2.8.21/src",

    "sys":"Linux"

}

查看zk中的slot状态:

[zk: 127.0.0.1:2181(CONNECTED) 3] ls /codis3/codis-demo/slots

1

[zk:127.0.0.1:2181(CONNECTED)3]ls/codis3/codis-demo/slots

前面initslots初始化的所有Slot都保存在slots路径下,每个Slot是一个结点。随便选取一个Slot结点,用get命令能够查看结点上附着的数据:

[zk: 127.0.0.1:2181(CONNECTED) 4] get /codis3/codis-demo/slots/slot-0334 {    "id": 334,    "group_id": 1,    "action": {} }

1

2

3

4

5

6

[zk:127.0.0.1:2181(CONNECTED)4]get/codis3/codis-demo/slots/slot-0334

{

    "id":334,

    "group_id":1,

    "action":{}

}

查询zk中的server状态:

[zk: 127.0.0.1:2181(CONNECTED) 5] get /codis3/codis-demo/group/group-0001 { "id": 1, "servers": [ { "server": "10.0.60.152:6379", "action": {} }, { "server": "10.0.60.154:6379", "action": { "state": "synced" } } ], "promoting": {} }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

[zk:127.0.0.1:2181(CONNECTED)5]get/codis3/codis-demo/group/group-0001

{

"id":1,

"servers":[

{

"server":"10.0.60.152:6379",

"action":{}

},

{

"server":"10.0.60.154:6379",

"action":{

"state":"synced"

}

}

],

"promoting":{}

}

查询zk中的proxy状态:

[zk: 127.0.0.1:2181(CONNECTED) 6] ls /codis3/codis-demo/proxy/proxy- proxy-919ce168362a7286e4081b600a00ca67 proxy-cdcec3cebe703a67688bb0fc3de21f76 proxy-b87c96f0bc6d8e62f196369c66cea7c2

1

2

3

[zk:127.0.0.1:2181(CONNECTED)6]ls/codis3/codis-demo/proxy/proxy-

proxy-919ce168362a7286e4081b600a00ca67proxy-cdcec3cebe703a67688bb0fc3de21f76

proxy-b87c96f0bc6d8e62f196369c66cea7c2

[zk: 127.0.0.1:2181(CONNECTED) 7] get /codis3/codis-demo/proxy/proxy-919ce168362a7286e4081b600a00ca67 { "id": 1, "token": "919ce168362a7286e4081b600a00ca67", "start_time": "2016-10-13 19:55:09.532570818 +0800 CST", "admin_addr": "10.0.60.152:11080", "proto_type": "tcp4", "proxy_addr": "10.0.60.152:19000", "product_name": "codis-demo", "pid": 4532, "pwd": "/usr/local/codis/src/github.com/CodisLabs/codis/extern/redis-2.8.21/src", "sys": "Linux" }

1

2

3

4

5

6

7

8

9

10

11

12

13

[zk:127.0.0.1:2181(CONNECTED)7]get/codis3/codis-demo/proxy/proxy-919ce168362a7286e4081b600a00ca67

{

"id":1,

"token":"919ce168362a7286e4081b600a00ca67",

"start_time":"2016-10-13 19:55:09.532570818 +0800 CST",

"admin_addr":"10.0.60.152:11080",

"proto_type":"tcp4",

"proxy_addr":"10.0.60.152:19000",

"product_name":"codis-demo",

"pid":4532,

"pwd":"/usr/local/codis/src/github.com/CodisLabs/codis/extern/redis-2.8.21/src",

"sys":"Linux"

}

要是想系统重做,删除此产品即可:rmr /codis3/codis_demo。

Codis常见问题修复

使用codis-admin命令行管理工具进行修复。

1)codis-dashboard异常退出的修复

当codis-dashboard启动时,会在外部存储上存放一条数据,用于存储 dashboard 信息,同时作为LOCK存在。当codis-dashboard安全退出时,会主动删除该数据。

当codis-dashboard异常退出时(大多数情况zookeeper连接异常时会异常退出),由于之前LOCK未安全删除,重启往往会失败。因此codis-admin提供了强制删除工具:

1、确认codis-dashboard进程已经退出(很重要);

2、然后运行codis-admin删除LOCK:

codis-admin --remove-lock --product=codis_demo --zookeeper=127.0.0.1:2181

1

codis-admin--remove-lock--product=codis_demo--zookeeper=127.0.0.1:2181

或者删除topom

[zk: 127.0.0.1:2181(CONNECTED) 13] rmr /codis3/codis-demo/topom

1

[zk:127.0.0.1:2181(CONNECTED)13]rmr/codis3/codis-demo/topom

正常关闭codis-dashboard:

codis-admin --dashboard=10.0.60.152:18080 --shutdown

1

codis-admin--dashboard=10.0.60.152:18080--shutdown

2)codis-proxy异常退出的修复

通常codis-proxy都是通过codis-dashboard进行移除,移除过程中codis-dashboard为了安全会向codis- proxy发送offline指令,成功后才会将proxy 信息从外部存储中移除。如果codis-proxy异常退出,该操作会失败。此时可以使用codis-admin工具进行移除:

1、确认codis-proxy进程已经退出(很重要);

2、运行codis-admin删除proxy,首先查看proxy状态:

codis-admin --dashboard=10.0.60.152:18080 --proxy-status

1

codis-admin--dashboard=10.0.60.152:18080--proxy-status

或用

codis-admin --dashboard=10.0.60.152:18080 --list-proxy

1

codis-admin--dashboard=10.0.60.152:18080--list-proxy

根据查看到的信息,强制删除报错的codis-proxy。

codis-admin --dashboard=10.0.60.152:18080 --remove-proxy --token=6a2db3c9ac07ba8857d4bc79ca6d191c  --force

1

codis-admin--dashboard=10.0.60.152:18080--remove-proxy--token=6a2db3c9ac07ba8857d4bc79ca6d191c --force

codis-admin --dashboard=10.0.60.152:18080 --remove-proxy --addr=127.0.0.1:11080 --force

1

codis-admin--dashboard=10.0.60.152:18080--remove-proxy--addr=127.0.0.1:11080--force

选项–force表示,无论offline操作是否成功,都从外部存储中将该节点删除。所以操作前,一定要确认该codis-proxy进程已经退出。

codis-proxy正常关闭

codis-admin --proxy=10.0.60.152:11080 --auth="xxxxx" --shutdown

1

codis-admin--proxy=10.0.60.152:11080--auth="xxxxx"--shutdown

3)jodis连接proxy显示Proxy list is empty问题处理

参考:https://github.com/CodisLabs/jodis/issues/10

codis数据迁移

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

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

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

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

codis-proxy高可用问题?

因为codis-proxy是无状态的,可以比较容易的搭多个实例,达到高可用性和横向扩展。对Java用户来说,可以使用基于Jedis的实现Jodis,来实现proxy层的HA:

  • 它会通过监控zookeeper上的注册信息来实时获得当前可用的proxy列表,既可以保证高可用性;

  • 也可以通过轮流请求所有的proxy实现负载均衡。

对于其他语言,可以使用haproxy代理到后端的多个codis-proxy,达到负载均衡的作用。而haproxy的单点问题可以使用keepalive做HA,这样就可以实现一个高可用高并发的codis-proxy了。

codis-dashboard高可用问题?

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

但需要注意的是对于同一个业务集群而言,同一个时刻codis-dashboard只能有0个或者1个。另外所有对集群的修改都必须通过 codis-dashboard完成。由于本身的限制,codis-dashboard无法做到高可用。也就是说如果你集群中的codis- dashboard挂掉了,那么你将无法对集群做出更改操作,另外你的codis-fe界面也会异常(获取不到数据),但值得庆幸的是此时你的 codis-集群对外服务不会出现任何问题。你需要做的就是去集群中的其他节点开启codis-dashboard即可,此时会重新去zookeeper 中注册信息,集群操作不会有任何问题,所以也不必太担心codis-dashboard挂掉了,只需要做好监控及时报警即可。

另外,此时的codis-fe需要更改一下配置文件,也就是把codis-dashboard的地址更换为新的codis-dashboard主机即可;然后重新启动codis-fe,此时整个codis集群又恢复了最初的完整性,期间不会对客户端连接造成任何影响。

Redis高可用问题?

对下层的redis实例来说,当一个group的master挂掉的时候,应该让管理员清楚,并手动的操作,因为这涉及到了数据一致性等问题 (redis的主从同步是最终一致性的)。因此codis不会自动的将某个slave升级成master。关于外部codis-ha工具(具体可以参考之 前的章节),这是一个通过codis-dashboard开放的RESTful API实现自动切换主从的工具。该工具会在检测到master挂掉的时候主动应用主从切换策略,提升单个slave成为新的master。

需要注意,codis将其中一个slave升级为master时,该组内其他slave实例是不会自动改变状态的,这些slave仍将试图从旧的 master上同步数据,因而会导致组内新的master和其他slave之间的数据不一致。因此当出现主从切换时,需要管理员手动创建新的sync action来完成新master与slave之间的数据同步(codis-ha不提供自动操作的工具,因为这样太不安全了)。

codis-fe安全问题?

默认情况下,codis-fe图形化界面没有任何安全措施,任何人只要知道地址都可以登录操作codis集群。此时你可以借助nginx/Apache的访问控制来进行codis-fe访问控制。提高codis-fe安全性。

Codis相关脚本

标准多codis实例目录

# proxy_19000; $ mkdir -p /data/codis/proxy_19000/bash $ mkdir -p /data/codis/proxy_19000/conf $ mkdir -p /data/codis/proxy_19000/log $ mkdir -p /data/codis/proxy_19000/run # proxy_19001; $ mkdir -p /data/codis/proxy_19001/bash $ mkdir -p /data/codis/proxy_19001/conf $ mkdir -p /data/codis/proxy_19001/log $ mkdir -p /data/codis/proxy_19001/run

1

2

3

4

5

6

7

8

9

10

11

# proxy_19000;

$mkdir-p/data/codis/proxy_19000/bash

$mkdir-p/data/codis/proxy_19000/conf

$mkdir-p/data/codis/proxy_19000/log

$mkdir-p/data/codis/proxy_19000/run

 

# proxy_19001;

$mkdir-p/data/codis/proxy_19001/bash

$mkdir-p/data/codis/proxy_19001/conf

$mkdir-p/data/codis/proxy_19001/log

$mkdir-p/data/codis/proxy_19001/run

然后在各自的实例的/data/codis/proxy_19001/bash/目录下添加以下脚本即可。

1、start_dashboard.sh

#!/bin/bash # nohup codis-dashboard --ncpu=2 --config=../conf/dashboard.toml --log=../log/dashboard.log --log-level=WARN &

1

2

3

#!/bin/bash

#

nohupcodis-dashboard--ncpu=2--config=../conf/dashboard.toml--log=../log/dashboard.log--log-level=WARN&

2、add_group.sh

#!/bin/bash # # create group; codis-admin --dashboard=10.0.60.152:18080 --create-group --gid=1 codis-admin --dashboard=10.0.60.152:18080 --create-group --gid=2 # add host; codis-admin --dashboard=10.0.60.152:18080 --group-add --gid=1 --addr=10.0.60.152:6379 codis-admin --dashboard=10.0.60.152:18080 --group-add --gid=1 --addr=10.0.60.154:6379 codis-admin --dashboard=10.0.60.152:18080 --group-add --gid=2 --addr=10.0.60.153:6380 codis-admin --dashboard=10.0.60.152:18080 --group-add --gid=2 --addr=10.0.60.154:6380 # configuration maser/slave; codis-admin --dashboard=10.0.60.152:18080 --sync-action --create --addr=10.0.60.154:6379 codis-admin --dashboard=10.0.60.152:18080 --sync-action --create --addr=10.0.60.154:6380

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

#!/bin/bash

#

# create group;

codis-admin--dashboard=10.0.60.152:18080--create-group--gid=1

codis-admin--dashboard=10.0.60.152:18080--create-group--gid=2

 

# add host;

codis-admin--dashboard=10.0.60.152:18080--group-add--gid=1--addr=10.0.60.152:6379

codis-admin--dashboard=10.0.60.152:18080--group-add--gid=1--addr=10.0.60.154:6379

codis-admin--dashboard=10.0.60.152:18080--group-add--gid=2--addr=10.0.60.153:6380

codis-admin--dashboard=10.0.60.152:18080--group-add--gid=2--addr=10.0.60.154:6380

 

# configuration maser/slave;

codis-admin--dashboard=10.0.60.152:18080--sync-action--create--addr=10.0.60.154:6379

codis-admin--dashboard=10.0.60.152:18080--sync-action--create--addr=10.0.60.154:6380

4、start_proxy.sh

#!/bin/bash # nohup codis-proxy --ncpu=2 --config=../conf/proxy.toml --log=../log/proxy.log --log-level=WARN &

1

2

3

#!/bin/bash

#

nohupcodis-proxy--ncpu=2--config=../conf/proxy.toml--log=../log/proxy.log--log-level=WARN&

5、start_fe.sh

#!/bin/bash # nohup `which codis-fe` --ncpu=2 --log=../log/fe.log --log-level=WARN --dashboard-list=../conf/codis.json --listen=0.0.0.0:8080 &

1

2

3

#!/bin/bash

#

nohup`which codis-fe`--ncpu=2--log=../log/fe.log--log-level=WARN--dashboard-list=../conf/codis.json--listen=0.0.0.0:8080&

6、initslot.sh

codis-admin --dashboard=10.0.60.152:18080 --slot-action --create-range --beg=0 --end=511 --gid=1 codis-admin --dashboard=10.0.60.152:18080 --slot-action --create-range --beg=512 --end=1023 --gid=2

1

2

codis-admin--dashboard=10.0.60.152:18080--slot-action--create-range--beg=0--end=511--gid=1

codis-admin--dashboard=10.0.60.152:18080--slot-action--create-range--beg=512--end=1023--gid=2

注意按照顺序依次启动即可。由于codis一旦跟zookeeper连接出现异常后codis-proxy就会异常退出,所以需要写一个计划任务监控脚本当codis_proxy异常退出时就报警并且自动拉起来。

#!/bin/bash IP=10.0.60.152 PORT="19000 190001" TIME=`date +%Y-%m-%d-%H-%M` for port in $PORT;do ps aux | grep -v grep | grep $port | grep codis-proxy &> /dev/null ret=$? if [ $ret -eq 0 ]; then    echo "$TIME codis ${IP}:${port} is exist !" >> /data/codis/proxy_${port}/log/codis.log else    msg="$TIME codis ${IP}:${port} is down!"            /usr/bin/curl    http://10.0.8.51:8888/sms/send  -d  "from=1000&to=15210491149&msg=$msg"    echo "$TIME codis ${IP}:${port} is not exist !" >> /data/codis/proxy_${port}/log/codis.log            cd /data/codis/proxy_${port}/bash            sh start_proxy.sh > /dev/null 2>&1    sleep 2            sh set_proxy_online.sh > /dev/null 2>&1    sleep 2 fi done

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#!/bin/bash

IP=10.0.60.152

PORT="19000 190001"

TIME=`date+%Y-%m-%d-%H-%M`

forport in$PORT;do

psaux|grep-vgrep|grep$port|grepcodis-proxy&>/dev/null

ret=$?

if[$ret-eq0];then

    echo"$TIME codis ${IP}:${port} is exist !">>/data/codis/proxy_${port}/log/codis.log

else

    msg="$TIME codis ${IP}:${port} is down!"

            /usr/bin/curl    http://10.0.8.51:8888/sms/send  -d  "from=1000&to=15210491149&msg=$msg"

    echo"$TIME codis ${IP}:${port} is not exist !">>/data/codis/proxy_${port}/log/codis.log

            cd/data/codis/proxy_${port}/bash

            shstart_proxy.sh>/dev/null2>&1

    sleep2

            shset_proxy_online.sh>/dev/null2>&1

    sleep2

fi

done

完结。

      本文转自一百个小排 51CTO博客,原文链接:http://blog.51cto.com/anfishr/1975386,如需转载请自行联系原作者






相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4月前
|
存储 分布式计算 负载均衡
在Linux中,什么是集群,并且列出常见的集群技术。
在Linux中,什么是集群,并且列出常见的集群技术。
|
7月前
|
Linux
Linux下Zookeeper分布式安装与配置
Linux下Zookeeper分布式安装与配置
294 0
|
消息中间件 Linux
Linux搭建RabbitMQ集群环境
Linux搭建RabbitMQ集群环境
348 0
|
Linux
Zookeeper :Linux下集群搭建
Zookeeper :Linux下集群搭建
129 0
|
SQL 存储 关系型数据库
Linux下搭建MySQL集群
一、MySQL集群简介 1、什么是MySQL集群 MySQL集群是一个无共享的(shared-nothing)、分布式节点架构的存储方案,其目的是提供容错性和高性能。 数据更新使用读已提交隔离级别(read-committedisolation)来保证所有节点数据的一致性,使用两阶段提交机制(two-phasedcommit)保证所有节点都有相同的数据(如果任何一个写操作失败,则更新失败)。
3730 0
|
存储 关系型数据库 MySQL
Linux之rhcs【红帽6的高可用】
Linux之rhcs【红帽6的高可用】 区别kvm qemu libvirtd virt-manager virsh kvm : 底层虚拟化 qemu : 用来虚拟化外围设备的,如IO设备(top命令可以看到虚拟机的进程都是qemu-kvm) libvirtd : 虚拟化接口,用来管理底层虚拟化的...
1917 0
|
关系型数据库 Java Linux
ZooKeeper分布式架构实战系列(02):Linux Ubuntu 18.04实战安装Zookeeper 3.4.13单节点模式
Linux Ubuntu 18.04实战安装Zookeeper 3.4.13单节点模式,后续我们会讲解Zookeeper集群模式的实战配置。
2250 0
|
测试技术 Linux 应用服务中间件
|
存储 负载均衡 关系型数据库