Codis 是一个分布式 Redis 解决方案

Codis源码地址:https://github.com/wandoulabs/codis

关于Codis组件可以参考:https://github.com/wandoulabs/codis/blob/master/doc/tutorial_zh.md

今天分享的这篇文章纯属个人的一些理解和使用的一些心得体会,如果错误也请朋友指出。

更重要的是为了认识一些正在使用或将要使用Codis的朋友有或多或少的帮助。

关于Codis的整体架构和功能介绍官方文档给的在详细不过了,所以我也不想在画蛇添足。

由于当前使用的是AWS的ec2主机,所以默认当前用户是ec2-user,而非root用户。

1、安装基础Go环境,所有节点均安装.

# sudo yum -y install gcc gcc-c++ make git wget go 
# sudo vim /etc/profile.d/go.sh
export GOPATH=/opt/mygo
export PATH=$GOPATH/bin:$JAVA_HOME/bin:$PATH
# source /etc/profile

2、安装Codis,除ZooKeeper节点外其余节点均正常安装.

# sudo mkdir /opt/mygo
# sudo chown -R ec2-user.ec2-user /opt/mygo/
# go get -u -d github.com/wandoulabs/codis
# cd /opt/mygo/src/github.com/wandoulabs/codis/
# make
# make gotest

3、安装ZooKeeper,仅需要在此节点安装.

# yum -y install java-1.8.0

# wget https://www.apache.org/dist/zookeeper/zookeeper-3.4.7/zookeeper-3.4.7.tar.gz
# tar -zxf zookeeper-3.4.7.tar.gz -C /opt
# cd /opt/zookeeper-3.4.7
# cp conf/zoo_sample.cfg conf/zoo.cfg
# mkdir /data/{zookeeper,logs} -p

# sudo vim conf/zoo.cfg
dataLogDir=/data/logs
dataDir=/data/zookeeper
server.1=localhost:2888:3888

# vim /data/zookeeper/myid
1

# vim /etc/profile.d/zookeeper.sh
PATH=$PATH:/opt/zookeeper-3.4.7/bin

# source /etc/profile
# sudo /opt/zookeeper-3.4.7/bin/zkServer.sh start conf/zoo.cfg

# netstat -alnut | grep 2181
# nc -v localhost 2181
# zkServer.sh status	#查看ZooKeeper的角色(leader|follower|standalone)

# zkCli.sh -server 127.0.0.1:2181
	ls /
	create /Test hellozk
	get /Test
	set /Test hellozookeeper
	get /Test
	delete /Test
	get /Test
	quit

4、启动codis-redis服务.仅需要在redis节点.

# sudo mkdir /etc/redis
# cd /opt/mygo/src/github.com/wandoulabs/codis
# sudo ./bin/codis-server /etc/redis/redis.conf
# sudo netstat -tnlp |grep codis-se

5、在dashbaord节点上操作.

1> 配置dashboard服务
# cd /opt/mygo/src/github.com/wandoulabs/codis/
# mkdir /etc/codis
# cp config.ini /etc/codis/codis-config.ini
# vim vim /etc/codis/codis-config.ini
zk=172.31.16.33:2181
product=cn_release_codis
dashboard_addr=localhost:18087
proxy_id=proxy_1
proto=tcp4

2> 启动dashboard服务
# cd /opt/mygo/src/github.com/wandoulabs/codis/
# ./bin/codis-config -c /etc/codis/codis-config.ini dashboard	

3> 初始化 slots(该命令会在zookeeper上创建slot相关信息)
# cd /opt/mygo/src/github.com/wandoulabs/codis/
# ./bin/codis-config -c /etc/codis/codis-config.ini slot init

4> 强制格式化slot
# ./bin/codis-config -c /etc/codis/codis-config.ini slot init

6、添加codis-group-redis

> 添加第一组codis

# ./bin/codis-config -c /etc/codis/codis-config.ini server add 1 172.31.51.119:6379 master
# ./bin/codis-config -c /etc/codis/codis-config.ini server add 1 172.31.51.125:6379 slave

> 添加第二组codis

# ./bin/codis-config -c /etc/codis/codis-config.ini server add 2 172.31.51.126:6379 master
# ./bin/codis-config -c /etc/codis/codis-config.ini server add 2 172.31.51.124:6379 slave

> 开启分片

# ./bin/codis-config -c /etc/codis/codis-config.ini slot range-set 0 511 1 online
# ./bin/codis-config -c /etc/codis/codis-config.ini slot range-set 512 1023 2 online

> 扩容,在线添加新分片

# ./bin/codis-config -c codis-config.ini server add 3 192.168.10.131:6381 master
# ./bin/codis-config -c codis-config.ini server add 3 192.168.10.132:6381 slave
# ./bin/codis-config -c codis-config.ini slot migrate 256 511 3

7、启动codis-proxy服务.

比如线上有两个Codis-proxy服务.

# cd /opt/mygo/src/github.com/wandoulabs/codis/
# mkdir /etc/codis
# cp config.ini /etc/codis/codis-proxy.ini 
# vim /etc/codis/codis-proxy.ini 
zk=172.31.51.123:2181
product=cn_release_codis
dashboard_addr=172.31.51.120:18087
proxy_id=proxy_1
proto=tcp4
# ./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

# cd /opt/mygo/src/github.com/wandoulabs/codis/
# mkdir /etc/codis
# cp config.ini /etc/codis/codis-proxy.ini 
# vim /etc/codis/codis-proxy.ini 
zk=172.31.51.123:2181
product=cn_release_codis
dashboard_addr=172.31.51.120:18087
proxy_id=proxy_2
proto=tcp4
# ./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

8、dashboard监控页面

http://<dashboard_ip>:18087/admin/

9、移除分片流程

---假设将分片3移除---
1. 设置codis-proxy为offline状态.
./bin/codis-config -c codis-config.ini proxy offline proxy_1

2. 迁移分片3上的数据到分片1
./bin/codis-config -c codis-config.ini slot migrate 256 511 1

3. 彻底移除分片3
./bin/codis-config -c codis-config.ini server remove-group 3

10、codis-server的HA

# export GOPATH=/opt/mygo
# go get github.com/ngaut/codis-ha
# cp /opt/mygo/bin/codis-ha /opt/mygo/src/github.com/wandoulabs/codis/bin/
# cd /opt/mygo/src/github.com/wandoulabs/codis/
# ./bin/codis-ha -codis-config="localhost:18087" -log-level="info" -productName="cn_release_codis"


遇到的问题以及解决办法,也希望这部分对朋友有用。

(1)

2015/12/11 16:49:10 dashboard.go:160: [INFO] dashboard listening on addr: :18087
2015/12/11 16:49:10 dashboard.go:234: [PANIC] create zk node failed
[error]: dashboard already exists: {"addr": "172.31.16.30:18087", "pid": 7762}

解决办法:

这种问题是由于使用了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的用户登录认证,配置如下。

当时我在做这个登录认证的时候,也花了2~3小时才解决,不是因为多么复杂,是因为dashboard很多都是基于api来获取数据的,如果少了配置中rewrite重定向那么就会只显示页面 而获取不到数据。切记

下一篇Codis文章补充部分:

  1. Codis集群中每个角色服务强烈建议成server式的服务启动脚本,这个我已经完成了,但是还是需要调整。
  2. 关于Dashboard服务的监控,由于是Redis主从,这个我也会在下篇讲解。
  3. 如果没有好的认证机制,建议关闭dashboard服务,而另外开发一个可查看但是没有权限操作的可视化界面。
时间: 2024-10-13 22:29:23

Codis 是一个分布式 Redis 解决方案的相关文章

[转载] Codis作者黄东旭细说分布式Redis架构设计和踩过的那些坑们

原文: http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=208733458&idx=1&sn=691bfde670fb2dd649685723f7358fea&scene=1&key=c76941211a49ab58cb17c68ecaeeda0f1c083d9508a0f6629461fff9025fd87de4706bd9c1730e0ddbab70568b34b16a&ascene=0&

Codis作者黄东旭细说分布式Redis架构设计和踩过的那些坑们

本次分享的内容主要包括五个大部分: Redis.RedisCluster和Codis; 我们更爱一致性; Codis在生产环境中的使用的经验和坑们; 对于分布式数据库和分布式架构的一些看法; Q & A环节. ??Codis是一个分布式Redis解决方案,与官方的纯P2P的模式不同,Codis采用的是Proxy-based的方案.今天我们介绍一下Codis及下一个大版本RebornDB的设计,同时会介绍一些Codis在实际应用场景中的tips.最后抛砖引玉,会介绍一下我对分布式存储的一些观点和看

细说分布式Redis架构设计和踩过的那些坑

摘要:本文章主要分成五个步骤内容讲解 Redis.RedisCluster和Codis; 我们更爱一致性; Codis在生产环境中的使用的经验和坑们; 对于分布式数据库和分布式架构的一些看法; Q & A环节. Codis是一个分布式Redis解决方案,与官方的纯P2P的模式不同,Codis采用的是Proxy-based的方案.今天我们介绍一下Codis及下一个大版本RebornDB的设计,同时会介绍一些Codis在实际应用场景中的tips.最后抛砖引玉,会介绍一下我对分布式存储的一些观点和看法

Codis——分布式Redis服务的解决方案

Codis——分布式Redis服务的解决方案 之前介绍过的 Twemproxy 是一种Redis代理,但它不支持集群的动态伸缩,而codis则支持动态的增减Redis节点:另外,官方的redis 3.0开始支持cluster. codis和twemproxy最大的区别有两个: codis支持动态水平扩展,对client完全透明不影响服务的情况下可以完成增减redis实例的操作: codis是用go语言写的并支持多线程,twemproxy用C并只用单线程. 后者又意味着:codis在多核机器上的性

豆瓣Redis解决方案Codis源码剖析:Proxy代理

豆瓣Redis解决方案Codis源码剖析:Proxy代理 1.预备知识 1.1 Codis Codis就不详细说了,摘抄一下GitHub上的一些项目描述: Codis is a proxy based high performance Redis cluster solution written in Go/C, an alternative to Twemproxy. It supports multiple stateless proxy with multiple redis instan

豆瓣Redis解决方案Codis源码剖析:Dashboard

豆瓣Redis解决方案Codis源码剖析:Dashboard 1.不只是Dashboard 虽然名字叫Dashboard,但它在Codis中的作用却不可小觑.它不仅仅是Dashboard管理页面,更重要的是,它负责监控和指挥各个Proxy的负载均衡(数据分布和迁移).并且,所有API都以RESTFul接口的形式对外提供,供Proxy和codis-config(Codis的命令行工具)调用.下面就来看一下数据分布和迁移的代码执行流程. Dashboard涉及到的知识点比较多,包括Martini框架

豆瓣Redis解决方案Codis安装使用

豆瓣Redis解决方案Codis安装使用 1.安装 1.1 Golang环境 Golang的安装非常简单,因为官网被墙,可以从国内镜像如studygolang.com下载. [root@vm root]$ tar -C /usr/local -zxf go1.4.2.linux-amd64.tar.gz [root@vm root]$ vim /etc/profile export GOROOT=/usr/local/go export PATH=$GOROOT/bin:$PATH export

分布式redis服务:codis

codis介绍 codis是豌豆荚基础架构团队开发并开源的分布式redis服务,可以看作是一个无限内存的redis服务,有动态扩容/缩容的能力. codis使redis获得动态扩容/缩容的能力,增减redis实例对client完全透明,并不需要重启服务,不需要业务方面担心redis内存爆掉的问题. codis架构 单codis-proxy架构 多codis-proxy架构 在codis的设计中,codis-proxy被设计成无状态的,客户端连接任何一个codis-proxy都是一样的,所以可以比

分布式Redis常见问题及解决方案精讲

前言考虑到绝大部分写业务的程序员,在实际开发中使用 Redis 的时候,只会 Set Value 和 Get Value 两个操作,对 Redis 整体缺乏一个认知. 所以我斗胆以 Redis 为题材,对 Redis 常见问题做一个总结,希望能够弥补大家的知识盲点. 正文本文围绕以下几点进行阐述: ◆为什么使用 Redis ◆使用 Redis 有什么缺点 ◆单线程的 Redis 为什么这么快 ◆Redis 的数据类型,以及每种数据类型的使用场景 ◆Redis 的过期策略以及内存淘汰机制 ◆Red