我的日常

登录/注册
您现在的位置:论坛 资料库 开源社区 > 基于Redis实现分布式消息队列(3)
总共48086条微博

动态微博

查看: 2052|回复: 0

基于Redis实现分布式消息队列(3)

[复制链接]
admin    

1244

主题

544

听众

1万

金钱

管理员

  • TA的每日心情

    2021-2-2 11:21
  • 签到天数: 36 天

    [LV.5]常住居民I

    管理员

    跳转到指定楼层
    楼主
    发表于 2016-02-05 13:41:18 |只看该作者 |倒序浏览
    1、Redis是什么鬼?
    Redis是一个简单的,高效的,分布式的,基于内存的缓存工具。
    假设好服务器后,通过网络连接(类似数据库),提供Key-Value式缓存服务。

    简单,是Redis突出的特色。
    简单可以保证核心功能的稳定和优异。

    2、性能
    性能方面:Redis是足够高效的。
    和Memecached对比,在数据量较小大情况下,Redis性能更优秀。
    数据量大到一定程度的时候,Memecached性能稍好。

    简单结论:但总体上讲Redis性能已经足够好。

    // Ref: Redis性能测试
    原则:Value大小不要超过1390Byte。

    经实验得知:
    List操作和字符串操作性能相当,略差,几乎可以忽略。
    使用Jedis自带pool,“每次从pool中取用完放回“ 和 “重用单个连接“ 相比,平均用时是3倍。这部分需要继续研究底层机制,采用更合理的实验方法进一步获得数据。
    使用Jedis自带pool,性能上是满足当前访问量需要的,等有时间了再进一步深入。

    3、数据类型
    Redis支持5种数据类型:字符串、Map、List、Set、Sorted Set。
    List特别适合用于实现队列。提供的操作包括:
    从左侧(或右侧)放入一个元素,从右侧(或左侧)取出一个元素,读取某个范围的元素,删除某个范围的元素。

    Sorted Set中元素是唯一的,可以通过名字找。
    Map可以高效地通过key找。
    假如我们需要实现finishTash(taskId),需要通过名字在队列中找元素,上面两个可能会用到。

    4、原子操作
    实现分布式队列首要问题是:不能出现并发问题。

    Redis是底层是单线程的,命令执行是原子操作,支持事务,契合了我们的需求。

    Redis直接提供的命令都是原子操作,包括lpush、rpop、blpush、brpop等。

    Redis支持事务。通过类似 begin…[cancel]…commit的语法,提供begin…commit之间的命令为原子操作的功能,之间命令对数据的改变对其他操作是不可见的。类似关系型数据库中的存储过程,同时提供了最高级别的事务隔离级别。

    Redis支持脚本,每个脚本的执行是原子性的。

    做了一下并发测试:
    写了个小程序,随机对List做push或pop操作,push的比pop的稍多。
    记录每次处理的详细信息到数据库。
    最后把List中数据都pop出来,详细记录每次pop详细信息。
    统计push和pop是否相等,统计针对每条数据是否都有push和pop。
    500并发,没有出现并发问题。

    5、集群
    实现分布式队列另一个重要问题是:不能出现单点故障。

    Redis支持Master-Slave数据复制,从服务器设置 slave-of master-ip:port 即可。
    集群功能可以由客户端提供。
    客户端使用哨兵,可自动切换主服务器。

    由于队列操作都是写操作,从服务器主要目的是备份数据,保证数据安全。

    如果想基于 sharding 做多master集群,可以结合 zookeeper 自己做。

    Redis 3.0支持集群了,还没细看,应该是个好消息,等大家都用起来,没什么问题的话,可以考虑试试看。

    如果 master 宕掉,怎么办?
    “哨兵”会选出一个新的master来。产生过程中,消息队列暂停服务。
    最极端的情况,所有Redis都停了,当消息队列发现Redis停止响应时,对业务系统的请求应抛出异常,停止队列服务。
    这样会影响业务,业务系统下订单、审批等操作会失败。如果可以接受,这是一种方案。
    Redis整个集群宕掉,这种情况很少发生,如果真发生了,业务系统停止服务也是可以理解的。

    如果想要在Redis整个集群宕掉的情况下,消息队列仍继续提供服务。
    方法是这样的:
    启用备用存储机制,可以是zookeeper、可以是关系型数据库、可以是另外可用的Memecached等。
    本地内存存储是不可取的,首先,同步多个客户端虚拟机内存数据太复杂,相当于自己实现了一个Redis,其次,保证内存数据存储安全太复杂。
    备用存储机制相当于实现了另外一个版本的消息队列,逻辑一致,底层存储不同。这个实现可以性能低一些,保证最基本的原则即可。
    想要保证不出现并发问题,由于消息队列程序同时运行在多个虚拟机中,对象锁、方法锁无效。需要有一个独立于虚拟机的锁机制,zookeeper是个好选择。
    将关系型数据库设置为最高级别的事务隔离级别,太傻了。除了zk有其他好办法吗?

    Redis集群整个宕掉的同时Zookeeper也全军覆没怎么办?
    这个问题是没有尽头的,提供了第二备用存储、第三备用存储、第四备用存储、…,理论上也会同时宕掉,那时候怎么办?
    有钱任性的土豪可以继续,预算有限的情况,能做到哪步就做到哪步。

    6、持久化
    分布式队列的应用场景和缓存的应用场景是不一样的。

    如果有没来得及持久化的数据怎么办?
    从业务系统的角度,已经成功发送给消息队列了。
    消息队列也以为Redis妥妥地收好了。
    可Redis还没写到日记里,更没有及时通知小伙伴,挂了。可能是断电了,可能是进程被kill了。

    后果会怎样?
    已经执行过的任务会再次执行一遍。
    已经放到队列中的任务,消失了。
    标记为已经完成的任务,状态变为“进行中”了,然后又被执行了一遍。
    后果不可接受。

    分布式队列不允许丢数据。
    从业务角度,哪怕丢1条数据也是无法接受的。
    从运维角度,Redis丢数据后,如果可以及时发现并补救,也是可以接受的。

    从架构角度,队列保存在Redis中,业务数据(包括任务状态)保存在关系型数据库中。
    任务状态是从业务角度确定的,消息队列不应该干涉。如果业务状态没有统一的规范和定义,从业务数据比对任务队列是否全面正确,就只能交给业务开发方来做。
    从分工上来看,任务队列的目的是管理任务执行的状态,业务系统把这个职责交给了任务队列,业务系统自身的任务状态维护未必准确。
    结论:任务队列不能推卸责任,不能丢数据是核心功能,不能打折扣。

    采用 Master-Slave 数据复制模式,配置bgsave,追加存储到aof。

    在从服务器上配置bgsave,不影响master性能。

    队列操作都是写操作,master任务繁重,能让slave分担的持久化工作,就不要master做。

    rdb和aof两种方法都用上,多重保险。
    appendfsync设为always。// 单节点测性能,连续100000次算平均时间,和per second比对,性能损失不大。
    性能会有些许损失,但任务执行为异步操作,无需用户同步等待,为了保证数据安全,这样是值得的。

    当运维需要重启Master服务器的时候,采取这样的顺序:
    1. 通过 cli shutdown 停止master服务器, master交代完后事后,关掉自己。这时候“哨兵”会找一个新的master出来。
    万万不可以直接kill或者直接打开防火墙中断master和slave之间的连接。
    master 对外防火墙,停止对外服务,Master 自动切换到其他服务器上, 原 Master 继续持久化 aof,发送到原来各从服务器。
    2. 在原 master 上进行运维操作。
    3. 启动原 master,这时候它已经是从服务器了。耐心等待它从新 master 获取最新数据。观察 redis 日志输出,确认数据安全。
    4. 对新的 master 重复1-3的操作。
    5. 将以上操作写成脚本,自动化执行,避免人为错误。


    科帮网 1、本主题所有言论和图片纯属会员个人意见,与本社区立场无关
    2、本站所有主题由该帖子作者发表,该帖子作者与科帮网享有帖子相关版权
    3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和科帮网的同意
    4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
    5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    7、科帮网管理员和版主有权不事先通知发贴者而删除本文


    JAVA爱好者①群:JAVA爱好者① JAVA爱好者②群:JAVA爱好者② JAVA爱好者③ : JAVA爱好者③

    快速回复
    您需要登录后才可以回帖 登录 | 立即注册

       

    关闭

    站长推荐上一条 /1 下一条

    发布主题 快速回复 返回列表 联系我们 官方QQ群 科帮网手机客户端
    快速回复 返回顶部 返回列表