Twemproxy HashTag的用法

来源:互联网 发布:解密 知乎 编辑:程序博客网 时间:2024/06/17 08:24

目前对于互联网公司不使用Redis的很少,Redis不仅仅可以作为key-value缓存,而且提供了丰富的数据结果如set、list、map等,可以实现很多复杂的功能;但是Redis本身主要用作内存缓存,不适合做持久化存储,因此目前有如SSDB、ARDB等,还有如京东的JIMDB,它们都支持Redis协议,可以支持Redis客户端直接访问;而这些持久化存储大多数使用了如LevelDB、RocksDB、LMDB持久化引擎来实现数据的持久化存储;京东的JIMDB主要分为两个版本:LevelDB和LMDB,而我们看到的京东商品详情页就是使用LMDB引擎作为存储的,可以实现海量KV存储;当然SSDB在京东内部也有些部门在使用;另外调研过得如豆瓣的beansDB也是很不错的。具体这些持久化引擎之间的区别可以自行查找资料学习。

 

Twemproxy是一个Redis/Memcached代理中间件,可以实现诸如分片逻辑、HashTag等功能;尤其在有大量应用服务器的场景下Twemproxy的角色就凸显了,能有效减少连接数。


Twemproxy设置

一旦涉及到一台物理机无法存储的情况就需要考虑使用分片机制将数据存储到多台服务器,可以说是Redis集群;如果客户端都是如Java没什么问题,但是如果有多种类型客户端(如PHP、C)等也要使用那么需要保证它们的分片逻辑是一样的;另外随着客户端的增加,连接数也会随之增多,发展到一定地步肯定会出现连接数不够用的;此时Twemproxy就可以上场了。主要作用:分片、减少连接数。另外还提供了Hash Tag机制来帮助我们将相似的数据存储到同一个分片。另外也可以参考豌豆荚的https://github.com/wandoulabs/codis。


基本配置

其使用YML语法,如

Java代码  收藏代码
  1. server1:  
  2.   listen: 127.0.0.1:1111  
  3.   hash: fnv1a_64  
  4.   distribution: ketama  
  5.   timeout:1000  
  6.   redis: true  
  7.   servers:  
  8.    - 127.0.0.1:6660:1  
  9.    - 127.0.0.1:6661:1  

server1:是给当前分片配置起的名字,一个配置文件可以有多个分片配置;

listen : 监听的ip和端口;

hash:散列算法;

distribution:分片算法,比如一致性Hash/取模;

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

  分片算法:

    ketama(一致性Hash算法)

    modula(取模)

    random(随机算法)

 

服务器列表

  servers:

   - ip:port:weight alias

  servers:

   - 127.0.0.1:6660:1

   - 127.0.0.1:6661:1

或者

  servers:

   - 127.0.0.1:6660:1 server1

 

   - 127.0.0.1:6661:1 server2

推荐使用后一种方式,默认情况下使用ip:port:weight进行散列并分片,这样假设服务器宕机换上新的服务器,那么此时得到的散列值就不一样了,因此建议给每个配置起一个别名来保证映射到自己想要的服务器。即如果不使用一致性Hash算法来作缓存服务器,而是作持久化存储服务器时就更有必要了(即不存在服务器下线的情况,即使服务器ip:port不一样但仍然要得到一样的分片结果)。


HashTag

比如一个商品有:商品基本信息(p:id:)、商品介绍(d:id:)、颜色尺码(c:id:)等,假设我们存储时不采用HashTag将会导致这些数据不会存储到一个分片,而是分散到多个分片,这样获取时将需要从多个分片获取数据进行合并,无法进行mget;那么如果有了HashTag,那么可以使用“::”中间的数据做分片逻辑,这样id一样的将会分到一个分片。

 

nutcracker.yml配置如下

Java代码  收藏代码
  1. server1:  
  2.   listen: 127.0.0.1:1111  
  3.   hash: fnv1a_64  
  4.   distribution: ketama  
  5.   redis: true  
  6.   hash_tag: "::"  
  7.   servers:  
  8.    - 127.0.0.1:6660:1 server1  
  9.    - 127.0.0.1:6661:1 server2  

 

连接Twemproxy

Java代码  收藏代码
  1. /usr/servers/redis-2.8.19/src/redis-cli  -p 1111  
Java代码  收藏代码
  1. 127.0.0.1:1111> set p:121  
  2. OK  
  3. 127.0.0.1:1111> set d:121  
  4. OK  
  5. 127.0.0.1:1111> set c:121  
  6. OK  

 

在我的服务器上可以连接6660端口 

Java代码  收藏代码
  1. /usr/servers/redis-2.8.19/src/redis-cli  -p 6660  
  2. 127.0.0.1:6660> get p:12:   
  3. "1"  
  4. 127.0.0.1:6660> get d:12:   
  5. "1"  
  6. 127.0.0.1:6660> get c:12:   
  7. "1"  

 

一致性Hash与服务器宕机

如果我们把Redis服务器作为缓存服务器并使用一致性Hash进行分片,当有服务器宕机时需要自动从一致性Hash环上摘掉,或者其上线后自动加上,此时就需要如下配置:

 

#是否在节点故障无法响应时自动摘除该节点,如果作为存储需要设置为为false

auto_eject_hosts: true

#重试时间(毫秒),重新连接一个临时摘掉的故障节点的间隔,如果判断节点正常会自动加到一致性Hash环上

server_retry_timeout: 30000

#节点故障无法响应多少次从一致性Hash环临时摘掉它,默认是2

server_failure_limit: 2

 

支持的Redis命令

不是所有Redis命令都支持,请参考https://github.com/twitter/twemproxy/blob/master/notes/redis.md。

 

因为我们所有的Twemproxy配置文件规则都是一样的,因此我们应该将其移到我们项目中。

Java代码  收藏代码
  1. cp /usr/servers/twemproxy-0.4.0/conf/nutcracker.yml  /usr/example/  

另外Twemproxy提供了启动/重启/停止脚本方便操作,但是需要修改配置文件位置为/usr/example/nutcracker.yml。

Java代码  收藏代码
  1. chmod +x /usr/servers/twemproxy-0.4.0/scripts/nutcracker.init   
  2. vim /usr/servers/twemproxy-0.4.0/scripts/nutcracker.init   

将OPTIONS改为

OPTIONS="-d -c /usr/example/nutcracker.yml"

 

另外注释掉. /etc/rc.d/init.d/functions;将daemon --user ${USER} ${prog} $OPTIONS改为${prog} $OPTIONS;将killproc改为killall。

 

这样就可以使用如下脚本进行启动、重启、停止了。

/usr/servers/twemproxy-0.4.0/scripts/nutcracker.init {start|stop|status|restart|reload|condrestart}

 

对于扩容最简单的办法是:

1、创建新的集群;

2、双写两个集群;

3、把数据从老集群迁移到新集群(不存在才设置值,防止覆盖新的值);

4、复制速度要根据实际情况调整,不能影响老集群的性能;

5、切换到新集群即可,如果使用Twemproxy代理层的话,可以做到迁移对读的应用透明。

0 0
原创粉丝点击