redis java 客户端服务器最佳实践

本文带大家入门市场上最佳的redis实践方案,redisson+codis。

一、为什么要使用redisson

这里介绍的是redis客户端方面的。

对于java客户端,现在市面上有jedis,jedis是redis官方推荐的,支持redisCluster、shardJedis、redis sentinel等多种功能。功能比较齐全。虽然都支持,但是redisCluster、redis sentinel都有各自的缺点,下面会介绍,那么支持也没有。shardjedis也是有缺点,因为每次增加减少或者修改redis服务器的ip,shardjedis都需要改变ip,这个是很麻烦的事情,下面也会介绍。

真正需要使用redisson的原因如下:参考

jedis使用阻塞的I/O,且其方法调用都是同步的,程序需要等到sockets处理完I/O才能执行,不支持异步。jedis客户端实例不是线程安全的,所以需要通过连接池来使用jedis;redisson使用非阻塞的I/O和基于netty的时间驱动的通讯层,其方法调用是异步的。Redisson的API是线程安全的,所以可以操作单个redission连接来完成各种操作。

所以,当数据量上来了之后,redisson的优点就体现出来了。

但是redisson也不能解决的一个问题就是服务器ip增加减少或者修改客户端都需要重新配置,解决的办法就是用下面的代理codis。

二、为什么要使用codis

这里介绍的是redis服务端方面的。

首先我们分析市面上几款产品:

redis sentinel:redis官方高可用的实现方案,数据量起来了之后,数据放在单台机器上会遇到容量和qps的瓶颈。redis sentinel只能实现高可用,不能实现不同的数据分布在不同的机器上。

redis cluster:redis官方集群实现方案,把槽slot分配给各个机器,数据再放到各个槽里面。可以实现分布式,每台单独的机器可以配置一个从节点,可以实现高可用。但是如果机器的ip和端口改变了,客户端的代码或者配置是需要修改的,在实际生产环境中使用会很苦恼。

shardjedis:这个其实属于的是客户端方面。但是因为它实现了hash一致性算法,并且使用了虚拟节点解决了节点分配不均的问题,这种一般是服务端解决的,所以放这里。并且添加或者减少节点的时候,只影响相邻的节点,这种用一致性hash实现的方法可以说是很优秀了,但是出现的问题和redis cluster 问题一样,如果机器的ip和端口改变了,需要修改配置。并且客户端分片,有多个客户端,容易造成数据的错误。

cachecloud:cachecloud是搜狐tv开发的,作为redis客户端服务器解决方案其实是不错的,服务端提供一个应用id,客户端连接这个id就可以。服务端修改ip和端口或者迁移数据对客户端都是透明的,客户端只要连接那个id就可以,所以可以解决我们遇到的所有问题。但是,使用这个方案总感觉有点跟不上主流,因为主流都用redisson或者jedis,客户端需要自己上传一个jar包到maven上面,然后在项目里面使用,如果这个使用熟悉了,就失去使用别的主流框架的机会,不过这个东西还是很好用。

Twemproxy:github地址,说实话,这个东西也是很常用的redisproxy方案,而且twitter开发的,必出精品,但是正如codis的git界面所展示的,codis是更加优秀:

redis java 客户端服务器最佳实践_第1张图片

twemproxy最大的缺点就是,reshard(迁移槽数据)之后,需要重启集群,这也是很难接受的;另外也没有图形界面。

哈哈哈,我们还是支持豌豆荚国产牌子吧

codis:这个就是codis,

参考

codis解决了如下问题:

通过1024个槽进行rehash从而可以平滑扩容缩容、避免单点故障和单点性能不足(高可用)、有图形界面、服务端操作对客户端透明、可以轻松将twemproxy迁移到codis。

codis唯一的瑕疵是 需要更改redis的源代码(为了加入slot信息),所以codis启动的是codis-server而不是redis-server

阿里的redis集群解决方案:阿里云,或者别的云,一般都有redis的集群解决方案,如果有钱并且对安全性要求不是特别特别高(需要使用自己的机房),直接用他们的解决方案就行了。


总结起来,如果数据量不大,直接使用redis-sentinel或者客户端分片的sharding jedis都可以了。但是要实现大规模数据,同时保证安全性(需要有自己的机房)又要便宜那就用redisson+codis。

三、如何使用redisson

1、先写一个redissonManager

  public class RedissonManager {
   
  private Config config = new Config();
   
  private Redisson redisson = null;
   
  public Redisson getRedisson() {
  return redisson;
  }
   
  private static String redis1Ip = PropertiesUtil.getProperty("redis1.ip");
  private static Integer redis1Port = Integer.parseInt(PropertiesUtil.getProperty("redis1.port"));
  private static String redis2Ip = PropertiesUtil.getProperty("redis2.ip");
  private static Integer redis2Port = Integer.parseInt(PropertiesUtil.getProperty("redis2.port"));
   
  @PostConstruct
  private void init(){
  try {
  config.useSingleServer().setAddress(new StringBuilder().append(redis1Ip).append(":").append(redis1Port).toString());
   
  redisson = (Redisson) Redisson.create(config);
   
  log.info("初始化Redisson结束");
  } catch (Exception e) {
  log.error("redisson init error",e);
  }
  }
 

把要使用的配置加入,如果有两个ip,可以加入两个

然后,这个就是使用方法:

  public class RedissonTest {
  private static final String CLOSE_ORDER_TASK_LOCK= "LOOK";
  public static void main(String[] args) {
  RedissonManager redissonManager = new RedissonManager();
  RLock lock = redissonManager.getRedisson().getLock(CLOSE_ORDER_TASK_LOCK);
  boolean getLock = false;
  try {
  if(getLock = lock.tryLock(0,50, TimeUnit.SECONDS)){
  log.info("Redisson获取到分布式锁:{},ThreadName:{}",CLOSE_ORDER_TASK_LOCK,Thread.currentThread().getName());
  int hour = Integer.parseInt(PropertiesUtil.getProperty("close.order.task.time.hour","2"));
  // iOrderService.closeOrder(hour);
  }else{
  log.info("Redisson没有获取到分布式锁:{},ThreadName:{}", CLOSE_ORDER_TASK_LOCK,Thread.currentThread().getName());
  }
  } catch (InterruptedException e) {
  log.error("Redisson分布式锁获取异常",e);
  } finally {
  if(!getLock){
  return;
  }
  lock.unlock();
  log.info("Redisson分布式锁释放锁");
  }
  }

四、如何使用codis

首先了解下codis,对codis的搭建心中有数,简单的codis图

redis java 客户端服务器最佳实践_第2张图片

最关键的就是proxy,codis-proxy为redis的代理,通过这个代理,redis客户端可以实现对redis服务器的访问。服务器的修改变化数据迁移等对客户端来说都是透明的。proxy可以实现HA。

接下去就是codis-redis-group,codis把redis分成多个group,每个group实际只能有一个master,master可以有多个slave,也就是codis的容量实际取决于group的多少。

再看一张完整的图片

redis java 客户端服务器最佳实践_第3张图片

codis是通过zookeeper协同数据的,另外还提供了dashboard方便用户管理集群,codis FE图形界面处理。codis adming 集群管理的命令行工具。

然后安装codis就看到如下界面:

redis java 客户端服务器最佳实践_第4张图片

redis java 客户端服务器最佳实践_第5张图片

可以看到,我们的proxy在19000端口启动,admin在11080端口启动。

又两个分组,一个占用513个slot,另外一个暂用511个slot

第一个group有两个redis,6381为master,6382为slave,可以在绿色的setting设置;第二个group只有6383一个服务器。上面会有new group添加group,add server把server添加到group里面。

如果需要使用多台机器,每台机器的zookeeper配置彼此即可,参考

五、如何结合使用redisson+codis

怎么使用,直接把19000这个proxy的端口放到redisson的port的配置里面即可。

你可能感兴趣的:(redis)