Redis需要代理吗?

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis需要代理吗?

引言

上期说到redis扩展,我们可以通过在Client端增加取模、随机、一致性哈希算法去实现,我们来做个大胆的实践推论。

客户端实现有问题吗

了不起上期所画的原理图中,可以清晰的看到,我们所实现的算法都在客户端。

现在假设我们有2个redis实例。

在真正的项目中,我们的微服务Client一般都有多个,有的甚至几十个,我们这里不说多了,就拿4个客户端。

client01、client02、client03、client04,这4个客户端是不是都要和后面的redis进行连接。client01和redis01连接、redis02连接,02、03、04同样也需要连接。

那么势必造成redis端的连接成本维护,只要客户端一多,连接成本直线上升。

增加代理层

如果你用过Nginx反向代理,那么你应该很轻松的就能联想到用代理来解决这个连接的问题。

每个redis实例只需要和代理进行连接就可以了。

而在代理层,我们只需要关注它的性能即可。

当大量client并发过来的时候,1台代理也撑不住了。

我们可以将代理层也反向代理了,加多一层负载均衡器。

通过使用LVS这个负载均衡器,在结合keepailved对LVS做一个主备,并且能监控到后端代理的健康状况。

这不过仅仅是我们自己的想法,这样一来反而有点因为技术而技术的赶脚了。

Redis作者本身也没有把Redis搞成多线程的,也不希望我们搞得更加复杂,那么我们前面讲了那么多,就是找一个代理层就可以了。

代理层应该是什么样

上期我们说到client端是有拆分算法的,那么我们就应该将算法放到代理层。

并且这个代理是无状态的。

我们去回忆下nginx,它就是无状态的,不管你前边和后边有多么复杂,有怎么样的数据逻辑交互,它都不关心。

也不需要关心,就只管做好自己代理转发的这个事情。

代理层应该具备的算法是:

  • modula
  • random
  • kemata

在kemata一致性哈希算法中,又有多个可以实现的方式:

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

实现redis代理的有哪些

  • twemproxy
  • predixy
  • cluster
  • codis

预分区

那么我们在思考下,这三种代理层算法或者模式好像都会有一个问题。

那就是不能作为数据库使用。

还有一种情况就是在我们使用过程中,redis实例的数量会随着我们业务的变化增加或者减少。

比如现在5月份有2台redis实例,到了年底由于业务的增加我们要扩展一台redis。

这个时候势必我们要迁移数据,就会对代理层的算法带来挑战,比如你之前使用的是hash,那么此次肯定就要所有数据重新hash了,也就是大家常听的rehash,要将数据重新分片。

那我们是不是也可以解决这种问题,比如我一开始就计划分区10个,至少到我业务增加到10台redis实例的时候,我都不用去改动,这个就叫做预分区。

什么意思,我来举个例子。

比如我们使用的是取模算法,我就取10个节点,数据分片是0.1.2.3.4.5.6.7.8.9。一开始我就只有2台,我的数据分片是redis1有0.1.2.3.4,redis2有5.6.7.8.9。当我新增一台redis3时,只需要将redis1中分片3.4和redis2中分片8.9迁移到redis3中,就可以了。此时重新建立mapping映射关系即可,迁移分片数据这个redis官方有操作,非常简单可靠,这样数据迁移就很方便了。

这种方式就不会影响你之前的算法,就是说你之前的算法找到当前这个数据在哪个分片,它这个数据还是在哪个分片里边,不会因为redis实例变化而重新改变算法。

redis cluster

接着上边的映射关系,其实redis自身连代理层都给你省了,有一个自身实现的无主模型。

也就是说redis客户端连谁都不重要,每个redis服务端的实例都是主。

它每个都有一样的算法比如hash%10,然后每个节点都保存着所有实例的映射关系,如图所示。

假如客户端要来get一个k1这个key,而这个k1经过哈希取模后得知数据存在第4个槽位或者是第四个分片。

当前客户端连着的是中间的redis2,指令到达redis2后经过算法一算,发现数据在分片4,然后发现自己没有分片4,在查询所有映射关系,找到分片4在redis3中。

返回给客户端说你去连接redis3获取,随后客户端切换到redis3,经过一样的步骤拿到分片4中的数据,然后返回。

总结

不过上边给的代理模式还是redis自身的cluster来说,都有一个问题,其实也不是问题,技术必然有取舍。

比如在redis cluster中我想要聚合2个key,一个key在分片3中,一个key在分片1中,你怎么办。

所以数据分治想聚合(取交集、并集、差集等)很难实现,当然了事务也很难实现,所以这就是redis作者的取舍,让计算向数据移动。

redis的特点就是快,要的就是效率,所以有些功能它就不支持,这是合理的。

经过本文的探讨,相信你对redis代理层、算法、redis自身的cluster模式有了一定的了解,下期我们接着聊。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
6月前
|
NoSQL 关系型数据库 MySQL
Docker安装详细步骤及相关环境安装配置(mysql、jdk、redis、自己的私有仓库Gitlab 、C和C++环境以及Nginx服务代理)
Docker安装详细步骤及相关环境安装配置(mysql、jdk、redis、自己的私有仓库Gitlab 、C和C++环境以及Nginx服务代理)
683 0
|
存储 NoSQL IDE
Spring认证指南:了解如何使用 Redis 作为消息代理
Spring认证指南:了解如何使用 Redis 作为消息代理
Spring认证指南:了解如何使用 Redis 作为消息代理
|
NoSQL API Redis
Python使用Redis实现IP代理池
Python使用Redis实现IP代理池
424 0
|
存储 NoSQL Redis
.NetCore+Jexus代理+Redis模拟秒杀商品活动
开篇叙 本篇将和大家分享一下秒杀商品活动架构,采用的架构方案正如标题名称.NetCore+Jexus代理+Redis,由于精力有限所以这里只设计到商品添加,抢购,订单查询,处理队列抢购订单的功能;有不足或者不够详细的还请见谅,顺手点个推荐也不错; a.
1369 0