赞
踩
Redis数据类型
键的类型只能是字符串
值支持5种数据类型:
字符串String,可以存储字符串、整数、浮点数
列表list
集合set
散列表hash,包含键值对的无序散列表
有序集合zset
Redis具体数据结构
字典:是集合的一种,集合中每个元素都是key-value键值对
跳跃表:是有序集合的底层实现之一,是基于多指针有序链表实现的,可以看成多个有序链表。
对于一个单链表来说,即使链表中存储的数据有序,查找数据也只能从头到尾遍历
想要提高效率,考虑在链表上建立索引,每两个节点提取一个节点到上一级。
查找时,从上层指针开始查找,找到对应区间之后再到下一层查找。
Redis的使用场景
缓存
会话缓存:存储多个应用服务器的会话信息,应用服务器无状态
消息队列:写入和读出消息
计数器
查找表:和缓存类似,如存储DNS记录;查找表内容不允许失效,缓存允许失效
分布式锁:分布式场景下,无法使用单机环境下的锁来对多个节点上的进程进行同步
都是非关系型内存键值数据库
键的过期时间
数据淘汰策略(算法)
可以设置内存最大使用量,当内存使用量超出时就会淘汰;
从以设置过期时间的数据中选择:volatile-lru、volatile-ttl(将要过期)、volatile-random
从全部数据中选择:allkeys-lru、allkeys-random
禁止驱逐数据:noeviction
一般使用allkeys-lru算法
数据持久化:将数据从内存中持久化到磁盘上
(事务)
一个事务包含多个命令,服务器执行事务期间,不会执行其他命令。
(事件)
Redis服务器是一个事件驱动程序
Redis主从复制
Redis主服务器,从服务器
可以设置主从链
Redis的Sentinel
哨兵,可以监听集群中的服务器,可以在主服务器下线时,自从从 从服务器中选举出新的主服务器
Redis的分片
将数据划分为多个部分,可以将数据存储到多台机器里面
缓存雪崩
如果缓存在某个时刻出现大规模的key失效,就会导致大量的请求直接打在数据库上,使得数据库压力巨大;如果在高并发的情况下,可能瞬间导致数据库宕机。
缓存击穿
某个热点key失效,大量并发请求集中访问,在缓存找不到;
就会引起高并发访问数据库,使得数据库压力剧增,可能导致数据库宕机;
缓存穿透
用户请求的数据在缓存中不存在,同时也在数据库中不存在;
导致用户每次请求该数据,都要去数据库中查询;
如果有恶意攻击者短时间内不断请求系统中不存在的数据,会导致短时间内有大量请求落在数据库上,从而使数据库宕机。
消息队列是分布式系统中重要的组件;
主要解决“应用解耦”、“异步消息”,“流量削峰”等问题;实现高性能,高可用,高伸缩和最终一致性架构。
目前使用较多的消息队列有ActiveMQ、RabbitMQ、kafka、RocketMQ等。
概念:
Topic:
从逻辑上讲一个Topic就是一个队列Queue;
从存储上讲一个Topic存储了一类相关的消息,是消息的集合。
Partition:
分是存在于服务端,且内部保持顺序,顺序不可变更的一个队列,用户存储消息。
在使用消息队列时用户感觉不到分区
一个Topic存储消息时会分为多个Partition,每个Partition内部消息是有顺序的。
类似于快递网点内有多家快递公司
Productor:
生产消息,生产完决定将消息发送到哪个Topic的哪个Partition
一个MQ中可以有多个种类的Topic种类消息,Patition先理解成一个Queue的内部存储
Consumer:
订阅Topic,消费内部的消息
Group:
用来标记Consumer的身份,拥有相同Group名称的Consumer是一个类Consumer,一般消费同一类消息。
Consumer之间是需要协同工作的,Productor之间一般是不相关的,不需要Group标记身份。
协同工作:两个consumer消费Topic消息,订单消息只能消费一次;如果行为相同的consumer只存在一个,就不存在协同工作了,但是存在单点问题和性能问题,因为大多数情况下是分布式系统。
集群消费:
一个消息只被消费一次,同一个Group内有多个Consumer,共同完成对一个Topic的消费。
上面说的Consumer协同工作就默认是集群消费了。
图中Consumer0和Consumer1属于同一个Group,假设Topic中有0到5共6条消息,Consumer0消费0-2,Consumer1消费3-5,他们共同完成了Topic中消息的消费。
这存在于大量的无状态的后台系统,就如上面说的消费订单消息进行发货的例子。(一个消息只被一个Consumer消费一次)
广播消费:
Topic中的每个消息会被同一个Group里的每个Consumer都消费一次;
如图Topic有0-5共6条消息,Consumer0会消费到0-5完整的6条消息,Consumer1也会消费0-5的6条消息。
这种消费往往应用在有状态的后台系统,比如多个缓存服务器,都要去消费消息,更新自己的缓存数据。
点对点模型
生产者向消息队列Topic中发送一个消息后,只能被一个消费者消费一次
发布订阅模型
生产者向Topic中发布了一个消息之后,所有订阅了该Topic的消费者都可以进行消费该消息,一个消息可以被消费多次。
(扩展:设计模式中“发送订阅模式”和“观察者模式”区别)
观察者模式中,Topic和观察者都知道对方的存在;而在发布订阅者模式中,生产者和消费者不知道对方的存在,它们通过Topic进行通信。
观察者模式是同步的,当事件触发,Topic会调用观察者的方法,然后等待方法的返回;
发布订阅模式是异步的,生产者向Topic发送一条消息,会立即返回,不关心消费者什么时候来消费这个消息。
异步处理
productor将消息发送给消息队列Topic之后,不需要等待consumer的处理,而是立即返回,可以进行其他操作。consumer从Topic中接收消息后进行异步处理。
例如在注册流程中,系统需要发送邮件验证用户合法性,可以使用消息队列使得 发送邮件的操作异步处理;用户注册完后就可以完成注册,而将“发送邮件”这一消息发送给消息队列。
但只有业务流程允许异步处理的情况下才能这么做。
流量削峰
高并发场景下,如果短时间内有大量请求到达,可能会压垮服务器和数据库;
可以将请求转发到消息队列中,业务处理服务器再根据其处理能力,从消息队列中订阅消息进行处理。
因为用户请求被放入消息队列中之后,请求就立即返回了。但是在后续的业务操作和数据库操作可能失败,因此使用消息队列进行异步处理之后,需要适当修改业务流程进行配合。例如在用户提交订单之后,订单数据写入MQ,不能立即返回给用户订单结果,需要在MQ中的消息被真正处理之后,再通过email或者短信通知用户订单结果,如手机订车票。
系统解耦
传统情况下系统模块之间进行直接调用,修改或新增一个模块会直接对其他模块产生影响。
通过使用MQ,一个模块只需要向MQ中发送消息,其他模块可以选择性的从MQ中订阅消息,从而完成调用,这样降低了系统耦合性。
利用发布订阅模式;消息发送者(生产者)发布消息,一个或多个消费者订阅消息,消息发送者和消息接收者并没有直接耦合,对新增业务而言,只要对某类消息感兴趣,就可以订阅该消息,对原有的系统和业务没有任何的影响。从而实现网站业务的可拓展性设计。
解决方案:
可用性问题:
MQ服务器使用集群,每次访问的是集群中的主服务器,当主服务器挂掉以后,备用服务器顶上。
复杂性问题
如何保证消息不被重复消费
消息被重复消费的原因大多是因为网络不通,确认消息没有传送到消息队列,导致MQ不知道自己已经消费过该消息了,再次将消息分发给其他消费者。三种解决思路:
如果消息是做数据库插入操作,给这个消息做一个唯一的主键,这样就算重复消费也会到导致主键冲突;不可取,数据库记录的主键一般是与业务无关的自增主键。
如果这个消息是做redis的set操作,那么不用解决,因为无论set几次结果都是一样的。
如果以上两种情况都不行,那么准备一个第三方来做消息记录。以redis为例,给消息分配一个全局id,只要消费过该消息,将<id,message>以键值对的形式写入redis。那么消费者开始消费前,先去redis中查看有没有消费记录即可。
选择一个支持消息持久化的方案:如RabiitMQ,给消息一个处理状态
如何保证消息的可靠传输
保证消息的可靠传输就是防止Productor弄丢数据,MQ弄丢数据,Consumer弄丢数据。
Productor弄丢数据:事务机制,生产者发送数据之前开启RabbitMQ事务,然后发送消息,如果消息没有被MQ接收到,生产者就会报错,此时就可以进行回滚,重新发送消息。
ack机制和超时重传:当MQ收到消息以后返回ack给Productor确认,如果在超时时间内Productor没有收到MQ的确认就重发该消息;
MQ丢失数据:开启MQ的持久化,即使MQ挂了重启以后还能恢复之前的数据
Consumer丢失数据:主要是消费时刚消费到,还没处理,进程就挂了;
关闭MQ的自动ack机制,只有消息真正处理完才手动返回给MQ一个ack;
如何保证从消息队列里拿到的数据按顺序执行
将需要保持顺序的消息放到同一个Topic里面,然后只用一个消费者去消费该Topic
数据是通过push还是通过pull方式给到Consumer比较好
其他问题:
大量消息在MQ中积压了几个小时还没解决?
临时紧急扩容:临时将Queue资源和consumer资源扩大10倍,以正常的10倍数据来消费数据。
消息队列过期失效:批量重新导入
消息队列满了:
消息队列详解_hc_ttxs的博客-CSDN博客_消息队列详解
ActiveMQ
RabbitMQ
RocketMQ
Kafaka——高吞吐量的分布式发布订阅MQ
单机吞吐量:10万级别,这是kafka最大的特点,吞吐量高,一般配合大数据系统来进行实时数据计算、日志采集等场景
Topic数量对吞吐量的影响:Topic从几十个到几百个的时候,吞吐量会大幅度下降;
所以在同等机器中,kafka尽量保证topic数量不要过多;如果需要大规模topic,需要增加更多机器资源
时效性:ms级别
可用性:非常高,kafka是分布式的,一个数据多个副本,少数机器宕机不会导致数据不可用
消息可靠性:经过参数优化配置,可以做到0丢失
功能支持:功能较为简单,主要支持简单的MQ功能;在大数据领域的实时计算和日志采集被大规模使用,是事实上的标准。
优劣势总结:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。