Twemproxy,Twitter 发布的 Redis 代理中间件

简介

由于单个redis实例对大内存管理能力有限(经验是6-8G比较适合,而内存的总大小尽量在系统内存的60%~80%,因为客户端、主从复制都是需要内存的,所以一个128G的内存最好分配称8G*10的redis实例),过大内存将导致redis性能大幅下降。所以我们需要redis集群来提高redis性能。

虽然2015年4月2号的时候redis的3.0.0发布了,支持redis cluster,但是还没有过生产环境的大幅应用来验证其可靠性,所以Twemproxy就成了我们现在对redis集群的最佳选择。

下面是其简单介绍,介绍的已经很详细了:

http://www.oschina.net/translate/twemproxy-a-twitter-redis-proxy

其实Twemproxy就是一个redis的代理,用于实现分片、HashTag、减少连接数等功能;尤其在有大量应用服务器的场景下Twemproxy的角色就凸显了,能有效减少连接数。

下面是集群的架构图

 

twemproxy代理架构
twemproxy代理架构

特性

  • 支持失败节点自动删除

可以设置重新连接该节点的时间 可以设置连接多少次之后删除该节点 该方式适合作为cache存储

  • 支持设置HashTag

通过HashTag可以自己设定将两个KEYhash到同一个实例上去。

  • 减少与redis的直接连接数

保持与redis的长连接 可设置代理与后台每个redis连接的数目

  • 自动分片到后端多个redis实例上

多种hash算法:能够使用不同的策略和散列函数支持一致性hash。 可以设置后端实例的权重

  • 避免单点问题

可以平行部署多个代理层.client自动选择可用的一个

  • 支持redis pipelining request

支持请求的流式与批处理,降低来回的消耗

  • 支持状态监控

可设置状态监控ip和端口,访问ip和端口可以得到一个json格式的状态信息串 可设置监控信息刷新间隔时间

  • 高吞吐量

连接复用,内存复用。 将多个连接请求,组成reids pipelining统一向redis请求。

缺点与不足

不支持针对多个值的操作,比如取sets的子交并补等(MGET 和 DEL 除外)。
不支持Redis的事务操作。
出错提示还不够完善。(发现错误命令就会返回服务器关闭了连接)
也不支持select操作。

其实Twemproxy不支持很多命令,但是大体上不影响使用,有些命令只支持根据分片规则设置过分片标签的key,下面会详细介绍各个配置参数。具体支持与不支持的命令如下:

https://github.com/twitter/twemproxy/blob/master/notes/redis.md

构建Twemproxy

linux上是非常容易构建的,但是需要这几个工具:autoconf、automake、libtool。安装方式大家自己google吧。接着执行如下命令构建:

$ git clone git@github.com:twitter/twemproxy.git
$ cd twemproxy
$ autoreconf –fvi
$ ./configure --enable-debug=full
$ make
$ src/nutcracker –h

这里要注意下,如上安装方式在有些服务器上可能在大量如mset时可能导致Twemproxy崩溃,需要使用如 CFLAGS="-O1" ./configure && make或CFLAGS="-O3 -fno-strict-aliasing" ./configure && make来安装。其实这些官方github上都有介绍:

https://github.com/twitter/twemproxy

配置

配置文件在conf/nutcracker.yml,下面是简单的配置样例:

alpha:是给当前分片配置起的名字,一个配置可以有多个分片策略。
listen:监听的ip和端口(ip:port或者name:port)。
hash:散列算法。
hash_tag:哈希标签。
distribution:分片算法。
timeout:连接后端Redis或接收响应的超时时间,默认是永久等待。
redis:是否是redis代理,如果是false则是memcached代理。
servers:代理的服务器列表,该列表会使用distribution配置的分片算法进行分片。

hash算法

one_at_a_time
md5
crc16
crc32 (crc32 implementation compatible with libmemcached)
crc32a (correct crc32 implementation as per the spec)
fnv1_64
fnv1a_64
fnv1_32
fnv1a_32
hsieh
murmur
Jenkins

哈希标签

允许使用key的一部分来分配键的存储位置。比如设置为{},则p:{id}:c和p:{id}:n会散列到一台服务器上。(我们仔细看下官方命令支持的文档,发现里面有一部分命令需要在一个实例的时候才支持使用,比如SUNION)

分片算法

  • ketama(一致性Hash算法):

ketama一致性hash算法,会根据服务器构造出一个hash ring,并为ring上的节点分配hash范围。ketama的优势在于单个节点添加、删除之后,会最大程度上保持整个群集中缓存的key值可以被重用。

  • modula(取模):

modula就是根据key值的hash值取模,根据取模的结果选择对应的服务器。

  • random(随机算法):

andom就是无论key值的hash是什么,都随机的选择一个服务器作为key值操作的目标。这种分片适合只读缓存。

servers

这个格式如下:

servers:
- ip:port:weight alias
- ip:port:weight alias

最好加上别名,这样可以在一个实例宕机的时候,更换机器只需要使用之前机器的别名,就可以继续映射了,如果没有别名,就得全部重新对应。

其他参数:

backlog
监听TCP 的backlog(连接等待队列)的长度,默认是512。
preconnect
是一个boolean值,指示twemproxy是否应该预连接pool中的server。默认是false。
server_connections
每个server可以被打开的连接数。默认,每个服务器开一个连接。
auto_eject_hosts
是一个boolean值,用于控制twemproxy是否应该根据server的连接状态重建群集。这个连接状态是由server_failure_limit阀值来控制。 默认是false。 (是否在节点故障无法响应时自动摘除该节点,如果作为存储需要设置为为false)
server_retry_timeout
单位是毫秒,控制服务器连接的时间间隔(重新连接一个临时摘掉的故障节点的间隔),在auto_eject_host被设置为true的时候产生作用。默认是30000 毫秒。
server_failure_limit
控制连接服务器的次数(节点故障无法响应多少次从一致性Hash环临时摘掉它),在auto_eject_host被设置为true的时候产生作用。默认是2。

关于key值长度的限制

memcache限制key值在250字符以内,redis则没什么限制,由于twemproxy将key值存放在连续的内存之中,所以twemproxy的key值的最大长度受到mbuf长度的限制。

mbuf的长度由-m指定,默认是16384字节,一般够用了。如果遇到key值过长的问题,可以调整这个参数。

mbuf的含义&调整

最小512字节,最大65536字节,默认16384字节。可以通过命令行的-m参数调整。

mbuf是twemproxy引以为傲的zero-copy技术的底层支撑,zero-copy意味着从客户端接收的数据直接被提交到redis-server,不需要经过中间的copy环节(看似不难,实际上操作起来很难做到)。

很明显,大尺寸的mbuf会增加性能,减少分包的次数,但是会增加对内存的消耗。

如何估计twemproxy的mbuf对内存的需求呢?公式如下:

max(client_connections, server_connections) * 2 * mbuf-size

因为存在client->twemproxy以及twemproxy->redis-server两个连接,所以mbuf是需要双份的。

大多客户端的连接会大于服务器连接池预设的连接数。我们假设1000个客户端连接,mbuf-size是16KB,那么大概会消耗掉1000*2*16KB=32M左右的内存。

启动

下面是启动参数:

Usage: nutcracker [-?hVdDt] [-v verbosity level] [-o output file]

[-c conf file] [-s stats port] [-a stats addr]

[-i stats interval] [-p pid file] [-m mbuf size]

Options:

-h, --help             : this help
-V, --version          : show version and exit
-t, --test-conf        : test configuration for syntax errors and exit
-d, --daemonize        : run as a daemon
-D, --describe-stats   : print stats description and exit
-v, --verbose=N        : set logging level (default: 5, min: 0, max: 11)
-o, --output=S         : set logging file (default: stderr)
-c, --conf-file=S      : set configuration file (default: conf/nutcracker.yml)
-s, --stats-port=N     : set stats monitoring port (default: 22222)
-a, --stats-addr=S     : set stats monitoring ip (default: 0.0.0.0)
-i, --stats-interval=N : set stats aggregation interval in msec (default: 30000 msec)
-p, --pid-file=S       : set pid file (default: off)
-m, --mbuf-size=N      : set size of mbuf chunk in bytes (default: 16384 bytes)

小结

使用Twemproxy时为了避免单点故障的问题,我们可以同时使用两个Twemproxy都代理那些redis节点,然后使用Jedis分片来使用。

另外豆瓣在去年年底出的Codis也是非常不错的,架构略有不同;同时使用Pre-Sharding机制,事先定好支持1024片,使得其扩容比较容易。性能测试结果好像很不错,同时支持Twemproxy的无缝迁移。

Redis Cluster

在这种机制下,没有中心节点(和代理模式的重要不同之处)。所以,一切开心和不开心的事情,都将基于此而展开。Redis Cluster将所有Key映射到16384个Slot中,集群中每个Redis实例负责一部分,业务程序通过集成的Redis Cluster客户端进行操作。客户端可以向任一实例发出请求,如果所需数据不在该实例中,则该实例引导客户端自动去对应实例读写数据。Redis Cluster的成员管理(节点名称、IP、端口、状态、角色)等,都通过节点之间两两通讯,定期交换并更新。

由此可见,这是一种非常“重”的方案。已经不是Redis单实例的“简单、可依赖”了。可能这也是延期多年之后,才近期发布的原因之一。

本文原创于赵伊凡BLOG

©原创文章,转载请注明来源: 赵伊凡's Blog
©本文链接地址: Twemproxy,Twitter 发布的 Redis 代理中间件

“Twemproxy,Twitter 发布的 Redis 代理中间件”的37个回复

  1. Pingback: Blue Coaster33
  2. Pingback: Business DIRECTV
  3. Pingback: tv packages
  4. Pingback: bedste lan lige nu
  5. Pingback: xnxx
  6. Pingback: stop parking
  7. Pingback: laan penge billigt
  8. Pingback: water ionizer
  9. Pingback: alkaline water
  10. Pingback: stop parking
  11. Pingback: water ionizer
  12. Pingback: locksmith queens
  13. Pingback: k bosch plumbers
  14. Pingback: our website
  15. Pingback: paypal loans
  16. Pingback: house blue
  17. Pingback: great post to read
  18. Pingback: ionizer loans
  19. Pingback: pay day loans
  20. Pingback: water ionizer
  21. Pingback: website
  22. Pingback: pay plan
  23. Pingback: alkaline water
  24. Pingback: alkaline water
  25. Pingback: read more
  26. Pingback: over here
  27. Pingback: he has a good point

发表评论

电子邮件地址不会被公开。 必填项已用*标注