赞
踩
1.纯内存访问
2.单线程避免上下文切换
3.渐进式ReHash, 缓存时间戳
全局哈希表,
数组扩容的时候, 元素移动的过程就叫做rehash
把一次大量拷贝的开销, 分摊到多次处理请求的过程中, 避免了耗时操作,
保证了数据的快速访问。
redis常用数据类型:string, list,set,zset, hash
bitmap可以用于布隆过滤器。
1.缓存
2.计数器
3.分布式会话
4.排行榜
5.最新列表
6.分布式锁
7.消息队列
1.使用redis过程中, cpu不是瓶颈, 受制于内存还有网络。
2.提高redis性能, Pipeline, 命令批量处理。每秒100万个请求。
3.单线程, 内部维护成本比较低。
4.如果多线程, 涉及到线程切换、加锁解锁,导致死锁问题。
5.惰性rehash,(渐进式Rehash)
1.单线程就够了小数据量包, 数据-> 内存, 响应时间100纳秒
比较小数据包 8W-10W QPS, 这个是极限值。
2.大公司需要更大的qps, 解决方案就是多线程, io的多线程。
(内部执行命令还是单线程),
3.为啥不采用分布式架构?
很大的缺点:服务器数量多, 维护成本高,
2.redis里面有很多命令, 不适用于数据分区。
3.数据分区无法解决热点读和热点写问题。
4.分布式架构会有数据倾斜, 重新分配,扩容或者缩容, 更加复杂。
多线程任务分摊到redis的同步IO中进行读写的负载。
string, hash, set , zset, list
1.redis的慢查询会记录下来,
2.redis的pipeline功能, 管道的功能,
3.watch命令, 观察变量有没有被修改。
4.redis+lua脚本实现限流,
5.redis持久化 ,
rdb:
aof:
主从复制:哨兵模式确保主故障后, 从节点选举, 从而达到高可用。
1.高性能
2.高并发
redis和memcached相对有哪些优势?
redis:
类型 支持内存, 非关系型数据库
支持string, list, set, zset, hash
支持事务(弱事务, 结合lua脚本实现比较完整的方案)
附加功能; 发布-订阅, 2.主从高可用(哨兵实现故障转移)
3.序列化支持, 4. lua脚本。
网络io模型:执行命令都是单线程, 网络操作上支持多线程
持久化支持:支持rdb 2.aof
memcached:
支持内存, key-value
支持文本, 二进制类型2种,
多线程服务支持。
网络io模型:多线程, 非阻塞io模式。
持久化支持:不支持
redis提供了简单的事务功能, 将一组需要一起执行的命令放到multi和exec之间
multi命令代表事务开始, exec代表事务结束, discard表示事务回滚。
redis所有数据结构都可以设置过期时间, 时间已到, 就会自动删除,
1.定期删除策略:
随机设置一个过期范围, 不能全部在同一时间过期。
2.惰性删除:
缓存淘汰算法:
可以使用布隆过滤器, bitmap,
一种概率的判断算法, 判断一个元素是否在一个集合中,
由bitmap数组和hash算法来实现。
误判问题:
通过hash计算在数组上不一定在集合上
本质是hash冲突
通过hash计算不在数组的一定不在集合
优化方案:
增大数组
增加hash函数。
使用布隆过滤器解决缓存穿透问题。
1.redis故障, -引入集群解决
2.redis中大量key ttl 过期, --尽量把ttl岔开, 随机ttl值
3.加入限流机制
4.加多级缓存。
可以使用SETNX 命令, 表示set if not exist
死锁问题避免方法就是在给这把锁一个失效时间。
分布式锁加入看门狗线程。
实现锁的续期。
基于stream实现队列:
bigkey就是key对应的value占用内存空间比较大, 例如一个字符串类型的value
可以最大存到512MB,
一个列表类型value最多可以存储23-1个元素。
一般认为超过10KB就是bigKey.
bigKey危害:
1.数据提前加载
2.增加缓存的存储空间, 提高缓存数据。
3.调整缓存的存储类型,
4.提升缓存更新频次
RDB:
是Redis database 缩写,
将瞬间形象记录下来,
数据越大, 可能会造成阻塞,
AOF: 写入命令就会有持久化, 命令追加文件
混合方式:高并发场景使用。
因为速度要求,
内存淘汰机制, 确保不会oom
更新类:
先更新数据库或者db都是不好的
3.先删除缓存, 再更新数据库。
延时双删:
4.先更新db, 再更新缓存。
redis cluster是redis分布式解决方案。
可以使用cluster达到负载均衡目的。
一般来说redis集群不会出现1000个节点以上。
集群中至少包含奇数个节点,
分槽的概念。
redis集群方案什么情况会导致整个集群不可用?
是一个分布式缓存中间件, 基于内存实现的key-value的no-sql数据库。
所有数据都放到内存里面,
提供了5种数据类型
string list set hash zset map
主从复制+哨兵
redis cluster-集群实现高可用。
主从集群
redis主从集群可以实现读写分离。但是不提供容错和恢复的功能。
一旦master节点挂了, 不会选举出新的master.
导致后续的客户端写请求直接失败。
redis提供了哨兵机制, 提供主从集群模式自动恢复能力。
哨兵会监控状态, 自动选举出master。
在线扩容问题没有解决。
redis-cluster模式:
redis-cluster里面实现了slot槽来实现分片模式, redis会根据key
去计算slot值,
引入了主从复制模式,
虽然解决了在线扩容提升读写性能
redis-cluster是多主多从的结构。
是单线程的,
6.0以后虽然是多线程, 但是是网络的
cpu不是瓶颈点。
加锁会带来性能上影响。
是数据持久化的方式,
将每个指令增加到aof文件中,
将aof文件中相同指令进行压缩, 减少占用空间。
1.根据内存数据, 构建aof文件
重写的过程放到后台的子进程去完成。
redis内存淘汰算法和
当内存使用率达到上限的时候的一种行为。
1.random算法, 随机移出
2.ttl算法
3.lru算法
4.lfu算法,
值得是master和slave之间实现数据同步的一种机制。
全量复制和增量复制。
全量复制:
增量复制是master收到数据变更的时候, 会将变动传给slave
有一个offset, 根据偏移量来读取。
Redis热点key指的是访问频率较高的key,当大量的请求集中在一个或少数几个热点key上时,会导致这些key所在的Redis节点的CPU、内存和网络带宽等资源被大量消耗,影响Redis集群的整体性能和稳定性。
Redis节点负载过高:当某些key被频繁访问时,会导致Redis节点负载过高,从而影响Redis的性能和稳定性。
Redis集群负载不均:当某些key被频繁访问时,会导致所在节点负载过重,而其他节点负载较轻,从而使Redis集群负载不均衡。
Redis集群性能下降:当某些key的访问频率特别高时,会导致Redis节点的CPU、内存、网络等资源负载过重,从而影响Redis的性能,甚至导致Redis宕机。
数据不一致:当某些key成为热点key时,如果数据量较大或者更新频率较快,可能会导致数据不一致的问题,比如缓存中的数据和数据库中的数据不一致,不同节点的数据不一致。
缓存击穿:当某些key的访问频率特别高时,如果这些key的数据过期或被删除,而恰好有大量的请求同时访问这个key,会导致这些请求直接访问后端数据库,从而造成缓存击穿的问题。
热点Key的产生通常与以下场景有关:
热点数据:某些数据具有较高的访问频率,例如热门商品、热门新闻、热门评论等。
业务高峰期:当处于业务高峰期的时候,某些数据会被频繁访问,例如双11秒杀、整点秒杀等。
代码逻辑问题:程序的代码逻辑导致部分Key被频繁访问,例如程序中的高频轮询或者存在代码死循环。
了解热点Key的概念和产生原因后,我们需要想一下如何检测和解决热点Key问题。
Redis提供了一些监控工具,如 Redis monitor 和 redis-stat,可以用来监控Redis实例的运行状态。通过这些工具,我们可以观察到访问频率较高的Key,以及它们对Redis性能的影响。
Redis monitor: 使用redis-cli的monitor命令,可以实时查看Redis实例的命令执行情况。通过分析输出的日志信息,可以找到访问频率较高的Key。
redis-stat: redis-stat是一个实时监控Redis实例的工具,它可以展示包括命令执行次数、内存使用情况等指标。通过观察这些指标,可以发现热点Key对Redis性能的影响。
Redis的慢查询日志记录了执行时间较长的命令,通过分析慢查询日志,可以找到可能存在热点Key的操作。可以使用redis-cli的slowlog命令查看慢查询日志。
通过上述方法,可以检测到热点Key及其对Redis性能的影响。在找到热点Key后,我们需要采取相应的策略来解决热点Key问题。
数据分片是通过将热点数据分散存储在多个Redis节点上,避免单个节点负载过高,是解决热点Key问题最常用的策略。
例如,在Redis Cluster模式下,数据自动按槽位分布在多个节点上,从而实现负载均衡。对于非Cluster模式,可以通过客户端或代理层实现一致性哈希等分片算法,将数据分布在多个Redis实例上。
读写分离可以将读操作与写操作分开处理,降低单个节点的负载。在主从复制模式下,可以将读操作分发到从节点上,从而分担主节点的压力。此外,可以使用代理层如Redis Sentinel或Twemproxy实现自动故障转移和读写分离。
缓存预热是指在系统启动或重启后,主动将热点数据加载到缓存中。这样,当用户访问这些热点数据时,可以直接从缓存中获取,避免对后端数据库造成压力。缓存预热可以通过定时任务或应用程序启动时加载热点数据实现。
限流是通过控制请求的速率来防止系统过载。在应用层实现限流,可以有效减轻热点Key对Redis的压力。常见的限流算法有漏桶算法和令牌桶算法。
熔断降级是在系统出现问题时,自动降低系统功能的一种策略。在应用层实现熔断降级,可以在Redis出现热点Key问题时,快速降低对Redis的访问压力。熔断降级可以通过开源工具如Hystrix实现。
通过上述策略,可以有效解决Redis的热点Key问题。然而,在实际应用中,需要根据具体业务场景和需求选择合适的策略。接下来,我们将通过实践案例来说明如何解决热点Key问题。
####1.redis主从模式:
一个主机器可以挂载多个从节点机器。
主写, 从读, 如果主机器宕机了, 那么就丧失了写功能, 只能去读。
支持10w的qps.
缺点: 主节点挂机, 从节点没办法升级为主节点, 相当于这个集群已经挂掉了。
特点就是,主从节点的数据是全量数据, 没有拆分的, 数据同步方式是异步的。
监控主服务器宕机, 那么从服务中选出新的主节点。
哨兵使用rust算法支持从从节点列表中选举出一个主节点。
qps的确很多的时候, 就需要用到分片集群。
每个数据值存储在其中一个机器上。
哈希槽就是存储的一个节点, 每次存储的时候, 会算出一个hash值。
三个哈希槽的话, hash值就分别是1-5000, 5000-10000, 10000-15000
其中每个节点中数据又有主从节点。
相当于不是存储的全量数据, 对于访问量很大的业务场景适用。
redis自身实现的redis-cluster分片集群。
redis提供了不同级别的持久化的方式:
1.rdb持久化方式能够在指定时间间隔对数据进行快照存储
2.aof持久化记录每次对服务器写的操作, 当服务器重启的时候, 会重新执行这些命令来恢复原始
数据,Aof命令以redis协议追加保存每次写的操作到文件末尾, redis还能对aof文件进行后台重写。
使得aof文件的体积不至于过大。
3.如果只希望数据运行时候存在。可以不使用任何持久化方式。
4.可以同时开启两种持久化方式, 这种情况下, 当redis重启时候, 会优先载入aof文件来恢复原始
数据, 因为在通常情况下aof文件保存的数据集要比rdb数据集完整。
是一个非常紧凑的文件, 保存了某个时间点的数据集, 非常适用于数据集的备份,
比如每小时保存一下过去24小时内的数据, 同时每天保存过去30天的数据, 这样即便出问题,
也可以根据需求恢复到不同版本的数据库。
rdb是一个紧凑的单一文件, 很方便传送到一个远端数据中心, 适用于容灾恢复。
rdb在保存文件时, 父进程唯一需要做的就是fork出一个子进程, 接下来工作就是由子进程完成。
父进程不需要再做其他IO操作, 所以rdb方式可以最大化redis性能。
与aof相比, 恢复大的数据集的时候, rdb方式会更快一些。
如果希望在redis宕机下丢失数据最少, rdb就不太适合, 虽然可以配置不同的save时间点,
例如每隔5分钟并且对数据集有100个写的操作, 是redis要完整的保存整个数据集是一个比较繁重的
工作, 通常会每间隔5分钟或者更久做一次保存, 万一在redis以外宕机, 那么可能丢失几分钟数据。
rdb需要经常fork出子进程来保存数据集到硬盘上, 当数据集比较大的时候fork的过程是非常耗时的。
可能会导致redis在一些毫秒级内不能响应客户端请求, 如果数据量巨大且cpu性能不是很好情况下,
这种情况会持续1秒, aof也需要fork, 但是可以调节重写日志文件频率来提高数据集持久度。
使用aof会让redis更加持久, 可以使用不同的sync策略, 无fsync, 每秒fsync,
每次写的fsync, 使用默认的每秒fsync策略,redis性能依然很好,
fsync是由后台线程进行处理的, 主线程会尽力处理客户端请求, 一旦出现故障,
最多丢失1秒数据。
aof文件是一个值进行追加的日志文件, 所以不需要写入seek, 即使由于某些原因(磁盘空间已满)
机器宕机等, 未执行完整的写入命令, 也可以通过使用redis-check-aof工具修复这些问题。
redis可以在aof文件空间体积变大的情况下自动在后台对aof进行重写,重写后新的
aof文件包含了恢复当前数据集所需的最小命令集,一旦新aof文件创建完毕, redis就会从
aof文件切换到新aof文件, 并开始对aof文件进行追加操作。
相同数据集来说, aof文件体积通常大于rdb文件体积。
根据所使用的fsync策略, aof的速度可能会慢于rdb, 一般情况下, 每秒fsync性能依然很高,
而关闭fsync可以让aof的速度和rdb一样快, 即使在高负载情况下也是如此,
不过在处理巨大的写入载入时, rdb可以更有保证的延迟时间。
Redis是一种内存数据库,它具有超时机制和淘汰机制来管理数据的过期和腾出空间。
超时机制:Redis允许为每个键设置过期时间。当键到达过期时间时,Redis会自动将其删除。这可以通过使用EXPIRE、PEXPIRE等命令来设置键的过期时间。超时机制是通过在内部维护一个定时器来实现的,在键过期时进行删除操作。超时机制使得Redis可以用于缓存等应用场景,确保数据的及时更新。
淘汰机制:当Redis的内存使用达到上限时,需要腾出一些空间来容纳新的数据。Redis提供了多种淘汰策略来决定要删除哪些键:
LRU(Least Recently Used):最近最少使用算法,根据键最近被访问的时间来选择淘汰键。
LFU(Least Frequently Used):最不经常使用算法,根据键被访问的频率来选择淘汰键。
Random:随机选择要淘汰的键。
TTL(Time to Live):基于键的剩余生存时间来选择淘汰键。
这些淘汰策略可以通过配置文件或使用CONFIG SET命令进行设置。默认情况下,Redis使用LRU算法作为淘汰策略,但可以根据需求选择合适的策略。
总结起来,Redis的超时机制允许为键设置过期时间,在到达过期时间后自动删除。而淘汰机制用于管理内存使用,通过选择合适的淘汰策略来删除一些键以腾出空间。这些机制使得Redis能够灵活地管理数据的生命周期和内存使用。
Redis分片集群是将数据分散存储在多个Redis节点上的一种集群部署方式。每个节点负责存储部分数据,从而实现横向扩展和负载均衡。这种分片集群方式有以下优点和缺点:
优点:
高性能横向扩展:通过增加新的Redis节点,可以线性地提高系统的读写吞吐量,有效地应对高并发访问和大规模数据存储需求。
负载均衡:分片集群可以将负载分散到多个节点上,避免单个节点成为性能瓶颈,提高系统的稳定性和可用性。
数据分布:数据被分散存储在多个节点上,减少了单个节点的内存占用,降低了内存压力,使得每个节点都能处理更多的数据。
高可用性:通过数据的复制和主从切换,可以实现数据的高可用性,即使有节点宕机,也可以从备份节点快速恢复服务。
灵活性:可以根据实际需求动态地增加或减少节点,实现弹性扩缩容,以适应不同阶段的负载变化。
缺点:
复杂性:分片集群需要对数据进行分片和路由,涉及到数据拆分和合并、节点选择、数据迁移等复杂操作,增加了系统的维护和管理难度。
数据一致性:在分片集群中,数据被拆分存储在多个节点上,如果数据分布不均匀或节点故障导致数据丢失,可能会影响数据的一致性和完整性。
事务支持受限:Redis在分片模式下对事务的支持受到限制,跨节点的事务操作可能会导致一致性问题。
跨节点操作复杂:涉及跨节点操作的数据处理可能比单节点操作更复杂,例如在分片集群中实现原子性的全局操作可能较为困难。
部分节点故障:如果一个或多个节点宕机,分片集群的可用性可能会下降,特别是对于没有备份节点的分片。
总体而言,Redis分片集群在高性能、负载均衡和高可用性方面有着明显的优势,但在设计和维护时需要考虑复杂性和数据一致性等问题。适用于对读写性能要求较高、并且数据量较大的场景。如果应用场景对数据的一致性要求非常高,可能需要更复杂的解决方案,如Redis主从复制和哨兵模式。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。