今天分享的这篇文章纯属个人的一些理解和使用的一些心得体会,如果错误也请朋友指出。
更重要的是为了认识一些正在使用或将要使用Codis的朋友有或多或少的帮助。
关于Codis的整体架构和功能介绍官方文档给的在详细不过了,所以我也不想在画蛇添足。
由于当前使用的是AWS的ec2主机,所以默认当前用户是ec2-user,而非root用户。
1、安装基础Go环境,所有节点均安装.
1
2
3
4
5
<code># sudo yum -y install gcc gcc-c++ make git wget go </code>
<code># sudo vim /etc/profile.d/go.sh</code>
<code>export</code> <code>GOPATH=</code><code>/opt/mygo</code>
<code>export</code> <code>PATH=$GOPATH</code><code>/bin</code><code>:$JAVA_HOME</code><code>/bin</code><code>:$PATH</code>
<code># source /etc/profile</code>
2、安装Codis,除ZooKeeper节点外其余节点均正常安装.
6
<code># sudo mkdir /opt/mygo</code>
<code># sudo chown -R ec2-user.ec2-user /opt/mygo/</code>
<code># go get -u -d github.com/wandoulabs/codis</code>
<code># cd /opt/mygo/src/github.com/wandoulabs/codis/</code>
<code># make</code>
<code># make gotest</code>
3、安装ZooKeeper,仅需要在此节点安装.
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
<code># yum -y install java-1.8.0</code>
<code># wget https://www.apache.org/dist/zookeeper/zookeeper-3.4.7/zookeeper-3.4.7.tar.gz</code>
<code># tar -zxf zookeeper-3.4.7.tar.gz -C /opt</code>
<code># cd /opt/zookeeper-3.4.7</code>
<code># cp conf/zoo_sample.cfg conf/zoo.cfg</code>
<code># mkdir /data/{zookeeper,logs} -p</code>
<code># sudo vim conf/zoo.cfg</code>
<code>dataLogDir=</code><code>/data/logs</code>
<code>dataDir=</code><code>/data/zookeeper</code>
<code>server.1=localhost:2888:3888</code>
<code># vim /data/zookeeper/myid</code>
<code>1</code>
<code># vim /etc/profile.d/zookeeper.sh</code>
<code>PATH=$PATH:</code><code>/opt/zookeeper-3</code><code>.4.7</code><code>/bin</code>
<code># sudo /opt/zookeeper-3.4.7/bin/zkServer.sh start conf/zoo.cfg</code>
<code># netstat -alnut | grep 2181</code>
<code># nc -v localhost 2181</code>
<code># zkServer.sh status #查看ZooKeeper的角色(leader|follower|standalone)</code>
<code># zkCli.sh -server 127.0.0.1:2181</code>
<code> </code><code>ls</code> <code>/</code>
<code> </code><code>create </code><code>/Test</code> <code>hellozk</code>
<code> </code><code>get </code><code>/Test</code>
<code> </code><code>set</code> <code>/Test</code> <code>hellozookeeper</code>
<code> </code><code>delete </code><code>/Test</code>
<code> </code><code>quit</code>
4、启动codis-redis服务.仅需要在redis节点.
<code># sudo mkdir /etc/redis</code>
<code># cd /opt/mygo/src/github.com/wandoulabs/codis</code>
<code># sudo ./bin/codis-server /etc/redis/redis.conf</code>
<code># sudo netstat -tnlp |grep codis-se</code>
5、在dashbaord节点上操作.
<code>1> 配置dashboard服务</code>
<code># mkdir /etc/codis</code>
<code># cp config.ini /etc/codis/codis-config.ini</code>
<code># vim vim /etc/codis/codis-config.ini</code>
<code>zk=172.31.16.33:2181</code>
<code>product=cn_release_codis</code>
<code>dashboard_addr=localhost:18087</code>
<code>proxy_id=proxy_1</code>
<code>proto=tcp4</code>
<code>2> 启动dashboard服务</code>
<code># ./bin/codis-config -c /etc/codis/codis-config.ini dashboard </code>
<code>3> 初始化 slots(该命令会在zookeeper上创建slot相关信息)</code>
<code># ./bin/codis-config -c /etc/codis/codis-config.ini slot init</code>
<code>4> 强制格式化slot</code>
6、添加codis-group-redis
> 添加第一组codis
<code># ./bin/codis-config -c /etc/codis/codis-config.ini server add 1 172.31.51.119:6379 master</code>
<code># ./bin/codis-config -c /etc/codis/codis-config.ini server add 1 172.31.51.125:6379 slave</code>
> 添加第二组codis
<code># ./bin/codis-config -c /etc/codis/codis-config.ini server add 2 172.31.51.126:6379 master</code>
<code># ./bin/codis-config -c /etc/codis/codis-config.ini server add 2 172.31.51.124:6379 slave</code>
> 开启分片
<code># ./bin/codis-config -c /etc/codis/codis-config.ini slot range-set 0 511 1 online</code>
<code># ./bin/codis-config -c /etc/codis/codis-config.ini slot range-set 512 1023 2 online</code>
> 扩容,在线添加新分片
<code># ./bin/codis-config -c codis-config.ini server add 3 192.168.10.131:6381 master</code>
<code># ./bin/codis-config -c codis-config.ini server add 3 192.168.10.132:6381 slave</code>
<code># ./bin/codis-config -c codis-config.ini slot migrate 256 511 3</code>
7、启动codis-proxy服务.
比如线上有两个Codis-proxy服务.
<code># cp config.ini /etc/codis/codis-proxy.ini </code>
<code># vim /etc/codis/codis-proxy.ini </code>
<code>zk=172.31.51.123:2181</code>
<code>dashboard_addr=172.31.51.120:18087</code>
<code># ./bin/codis-proxy -c /etc/codis/codis-proxy.ini -L /var/log/codis_proxy.log --cpu=1 --addr=172.31.51.122:19000 --http-addr=172.31.51.122:11000</code>
<code>proxy_id=proxy_2</code>
<code># ./bin/codis-proxy -c /etc/codis/codis-proxy.ini -L /var/log/codis_proxy.log --cpu=1 --addr=172.31.51.121:19000 --http-addr=172.31.51.121:11000</code>
8、dashboard监控页面
<a href="http://blog.51cto.com/467754239/1728423">http://<dashboard_ip>:18087/admin/</a>
<a href="http://s5.51cto.com/wyfs02/M00/78/7B/wKiom1Z9WMyCr7pXAABfLaMu-Ec810.png" target="_blank"></a>
9、移除分片流程
<code>---假设将分片3移除---</code>
<code>1. 设置codis-proxy为offline状态.</code>
<code>.</code><code>/bin/codis-config</code> <code>-c codis-config.ini proxy offline proxy_1</code>
<code>2. 迁移分片3上的数据到分片1</code>
<code>.</code><code>/bin/codis-config</code> <code>-c codis-config.ini slot migrate 256 511 1</code>
<code>3. 彻底移除分片3</code>
<code>.</code><code>/bin/codis-config</code> <code>-c codis-config.ini server remove-group 3</code>
10、codis-server的HA
<code># export GOPATH=/opt/mygo</code>
<code># go get github.com/ngaut/codis-ha</code>
<code># cp /opt/mygo/bin/codis-ha /opt/mygo/src/github.com/wandoulabs/codis/bin/</code>
<code># ./bin/codis-ha -codis-config="localhost:18087" -log-level="info" -productName="cn_release_codis"</code>
遇到的问题以及解决办法,也希望这部分对朋友有用。
(1)
<code>2015</code><code>/12/11</code> <code>16:49:10 dashboard.go:160: [INFO] dashboard listening on addr: :18087</code>
<code>2015</code><code>/12/11</code> <code>16:49:10 dashboard.go:234: [PANIC] create zk node failed</code>
<code>[error]: dashboard already exists: {</code><code>"addr"</code><code>: </code><code>"172.31.16.30:18087"</code><code>, </code><code>"pid"</code><code>: 7762}</code>
解决办法:
这种问题是由于使用了kill -9导致了dashboard服务异常终止,而退出服务的时候没有在zk上清除自已的信息,所以就出现了这种问题。
所以我们在停止codis集群的任何服务的时候都不要轻易使用kill -9,可以使用kill.
如果使用kill,那么服务在终止的时候也会自动的到zk上清除自已的信息,下次再启动的时候会立刻注册。
临时性的解决办法就是:
# rmr /zk/codis/db_codis_proxy_test/dashboard
(2)
dashboard提供的api接口
http://debugAddr/setloglevel?level=debug
http://debugAddr/debug/vars #主要是获取ops信息的还可以设置日志级别
浏览器访问proxy的debug_addr对应地址/debug/vars路径,可以看到每个proxy的qps信息。
(3)
codis-proxy的服务日志中产生的信息解释。
quit : client主动发的quit指令
EOF : 连接直接断开了,就是proxy从client的tcp读的时候遇到EOF了
codis每次主动关闭client的连接都会打log的,一般来说主要可能有:
非法操作、该请求连的底层redis挂了、这个session很久没请求触发了proxy这边的清理逻辑。
第三个可能更大些,看时间是6点多,是不是你们的访问量不大?
session_max_timeout=1800
如果30分钟内没有任何ops 那么codis就主动关闭这个连接。
嗯,主要是有人反馈说他们的环境下有时候client主动关了连接但是proxy这边没收到close的消息,导致proxy这边最后积累了一大堆连接把资源吃满了
(4)
NaN GB
因为redis配置文件中没有设置内存maxmemory参数
(5)
codis中所有的读写操作都是在redis-master上执行的,redis-slave只负责数据的冗余,当master出现down之后 可以进行master和slave的切换。
(6)******
在codis集群中product是用来区分是否为同一个集群的。所以如果是同一个集群,那么dashboard和codis-proxy中的product要设置的一样。否则就面临的下面这个问题
zk: node does not exist
codis-proxy配置文件中的proxy_id 是用来区分同一个集群下的不同成员,所以这个参数要唯一。
(7)
codis-ha只负责在master挂掉的时候自动选择一个slave提升为master,但没有把剩余的slave重新挂在新的master上,而且也没有确保选择的slave是最优的
(8)
Too many open files
在用python多线程对redis进行压力测试的时候,压力超过4000的时候就出现这种问题。
2台codis-proxy支持并发2-3w没有太大的问题。
(9)
dashboard服务即使停止也不会影响app通过codis-proxy正常的访问redis服务。
但是会影响codis-ha服务,则主备不会自动切换啦.
意思也就是dashboard服务如果停止,那么app还是可以正常访问redis的,但是codis-ha会终止运行期。
(10)
同一个group中可以实现redis数据的主从复制,但是不同的group中无法实现。
如果同一个group中所有的master和slave都挂掉了,那么数据就丢失了,但是你如果还查询挂掉的group中的key就会提示错误。并且那个key也就会占用啦。
所有的写操作codis-proxy就不会发送到挂掉的group上去了。
(11)
同一个Group中的codis-server 实例下,多个slave 是否会分担master的读请求?
codis的设计理念是更注重一致性,redis的主从同步不是强一致的,因此codis不支持读写分离
(12)
一个集群中只能有一个dashboard服务出于运行状态,可以有多个 但是同时只能有一个服务出于running状态。
如果正在使用Codis的朋友,那么肯定也会遇到这样一个问题,就是关于dashboard的登录认证问题。在这里我做了一个基于nginx的用户登录认证,配置如下。
<a href="http://s1.51cto.com/wyfs02/M02/78/7A/wKioL1Z9b_aDHql0AABFfwoiA-g909.png" target="_blank"></a>
<a href="http://s1.51cto.com/wyfs02/M02/78/7A/wKioL1Z9Wt6ibZb6AAAxqvS7_ls831.png" target="_blank"></a>
当时我在做这个登录认证的时候,也花了2~3小时才解决,不是因为多么复杂,是因为dashboard很多都是基于api来获取数据的,如果少了配置中rewrite重定向那么就会只显示页面 而获取不到数据。切记
下一篇Codis文章补充部分:
Codis集群中每个角色服务强烈建议成server式的服务启动脚本,这个我已经完成了,但是还是需要调整。
关于Dashboard服务的监控,我认为更多的是Redis主从,这个我也会在下篇讲解遇到Redis的坑。
由于dashboard没有友好的登录认证机制,建议关闭dashboard服务,而另外开发一个可查看但是没有权限操作的可视化界面。
本文转自zys467754239 51CTO博客,原文链接:http://blog.51cto.com/467754239/1728423,如需转载请自行联系原作者