首页 > 数据库 >redis

redis

时间:2024-04-26 11:11:44浏览次数:25  
标签:缓存 redis Redis 命令 数据 节点

一、redis为什么快

  • 1.基于内存:内存读写效率远高于磁盘读写

  • 2.存储形式:键值对的内存数据库,哈希表结构 O(1)时间复杂度可以获取值

  • 3.单线程:避免上下文切换

  • 4.IO多路复用 :单个线程处理多个客户端链接

  • 5.编码:支持多种数据结构及编码,根据元素数量,有阀值,大于小于阀值的编码不同

  • 6.渐进式ReHash:把一次性大量拷贝(数组移动)的开销,分摊到多次处理请求的过程中

  • 7缓存时间戳:由一个定时任务,每毫秒更新一次缓存,获取时间从缓存中直接拿

二、redis的应用场景

常用基本数据类型(8种)

名称 英文名 作用域
字符串 String 缓存、计数器、分布式session,分布式锁
哈希 hash 存放对象
列表 list 消息队列、文章列表
集合 set 标签、随机数、社交图谱
有序集合 zset 排行榜
Bitmaps Bitmaps 布隆过滤器
HyperLogLog HyperLogLog uv
Geo Geo redis3.2推出 用于存储地理位置信息

1.字符串(string)

  • 命令的时间复杂度
    • del、mset、mget支持多键操作,时间复杂度和键个数相关为 O(n)
    • getrange的 -> O(n)
    • 剩余全是O(1)
  • 缓存:具有支持高并发的特性,加速读写,降低后端压力
  • 计数器:实现快速计数、查询缓存的功能、同时数据可异步落地到其他数据源
  • 分布式会话:(共享session):将用户的session进行集中管理
  • 分布式锁:使用redis setnx来实现分布式锁

2.哈希(Hash)

  • 适用于存储对象,比string开发效率更高

3.列表(list)

用来存储多个有序字符串

  • 消息队列:lpush + brpop 命令组合实现阻塞队列:
    生产环境客户端使用lpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的”抢“列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性。
  • 文章列表:有序,且支持按照索引范围获取元素

4.集合(set)

  • 标签:同一标签:对于用户体验和增强用户粘性比较重要
  • 随机数:抽奖活动
  • 社交网络:点赞、粉丝数、共同好友、喜好、推送、下拉刷新等
    • sunion命令 : 返回多个set类型的并集
    • sinter命令:返回多个set类型的交集集
    • sdiff命令:返回多个set类型的差集

5.有序集合(zset)

  • 排行榜:多维度:时间、浏览量、获赞数

6.BitMaps(位数组实现):

bitmaps应用场景

  • 几亿用户系统签到
  • 去重登录次数统计
  • 某用户是否在线状态
    命令:setbit、getbit、bitcount
    bitmaps原理:redis内构一个足够长的数组,每个数组只能是0和1两个值,数组下标表示用户id,这个几亿长的大数组就可以通过下标和元素值(0和1)来构建一个记忆系统
  • 布隆过滤器:用于判断一个元素是否在一个集合中

7.HyperLogLog(基于概率有误差)

用于计算一个很大的元素集合的基数,基数是指集合中不同元素的数量。这种结构是用来处理大数据的,因为它会以极小的内存空间(通常每个元素只需要12字节)来计算基数。

  • UV : 统计每个网页每天的uc数据,不精确的去重计数方案,误差0.81%

8.Geo

常用结构命令

  • 1.geoadd:添加地理位置信息
    eg:geoadd cities 13.361389 38.115556 "Palermo"
  • 2.geopos:获取地理位置信息。
    eg:geopos cities "Palermo"
  • 3.geodist:获取两个地理位置的距离。
    eg:geodist cities "Palermo" "Catania" km
  • 4.georadius:根据用户给定的经纬度坐标来获取位于指定范围内的地理位置元素
    eg:georadius cities 15 37 100 km WITHCOORD WITHDIST WITHHASH
  • 5.georadiusbymember:根据位置元素所对应的坐标来获取位于指定范围内的地理位置元素。
    eg:georadiusbymember cities "Palermo" 100 km WITHCOORD WITHDIST WITHHASH
  • 6.geohash:获取一个或多个位置元素的 Geohash 值。
    eg:geohash cities "Palermo" "Catania"

三、为什么redis6.0引入多线程

redis6.0之前

  • redis的瓶颈不是cpu,受制于内存、网络
  • 提高redis性能,pipeline(命令批量)
  • 单线程,维护成本低,不需关注线程安全
  • 惰性rehash减少阻塞

redis6.0引入多线程之后:

本质:多线程任务 分摊到Redis 同步IO中,读写负载。

  • 1、小数据包。数据-》内存 响应时间 100ns 8w-10wQPS(极限)
  • 2、针对大的公司,需要更大的QPS,IO的多线程(内部执行命令还是单线程)
  • 3、为什么不采用分布式架构—很大的缺点。
    服务器数量多,维护成本高。Redis命令 不适用 需要数据分区,无法解决热点数据读写的问题。
    数据倾斜、重新分配、扩容、缩容,更加复杂

4.redis的高级功能

  • 1.慢查询
    快速定位系统中的慢操作,监测发生时间、耗时、命令的详细信息
  • 2.Pipeline:命令批量
  • 3.wathc命令
    确保事务中的key有没有被其他客户端修改过,才执行事务,否则不执行(类似于乐观锁)
  • 4.redis + lua语言实现限流
  • 5.分布式锁:setnx:加锁设置过期时间 + 看门狗续期
  • 6.高并发高可用
    • 1.主从复制
      提供了复制功能,实现了相同数据的多个Redis副本。每个主节点可以对应多个从节点,复制的数据流只能由主节点复制到从节点
    • 主从复制的问题
      • 需要手动晋升子节点,同时需要修改应用方的节点地址。
      • 主节点的写能力收到单机限制
      • 主节点的存储能力收到单机的限制
  • 7 哨兵(redis sentinel)
    主从复制模式下,主节点故障,需要人工将从节点晋升为主节点。
    2,8版本开始提供哨兵架构解决此问题。
    原理是哨兵通过发送命令(ping命令),等待Redis服务器响应,如果在指定时间内,主机Redis无响应,从机则判断主机宕机,选举从机上位,从而监控运行的多个Redis实例
    • 1.心跳机制:每个sentinel每秒一次向主从服务器发送ping命令,获取状态信息,心跳检测
    • 2.判断master节点是否下线(默认30s)
    • 3.基于Raft算法选举领头sentinel
    • 4.故障转移:选择一个slaver节点来作为master
      • 1.选择优先级最高的(replica-priority配置项)越小,优先级越高
      • 2.优先级相同,选择offset(偏移量)最大的,越多同步数据越多
      • 3.如果offset也相同,选择 run id 较小的
        通过以上4个步骤,s实现由Redis Sentinel自动完成故障发现和转移,实现自动高可用

Redis哨兵模式的优缺点

  • 哨兵模式优点:最大的优点就是主从可以自动切换,系统更健壮,可用性更高;
  • 哨兵模式缺点:最大的缺点就是还要多维护一套哨兵模式,实现起来也变的更加复杂增加维护成本;

5.redis的事务

本质:按照顺序串行化执行队列中的每个命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
顺序性、一次性、排他性 执行一个队列中的一系列命令。

命令 描述
EXEC 执行所有事务块命令
DISCARD 取消事务、放弃执行事务块所有命令
MULTI 标记一个事务块,开启事务
UNWATCH 取消watch命令对所有key的监视
WATCH 监视key,如果在事务执行前,该key被其他命令改动,事务将被打断
代码实例:
        //构建redis连接
        Jedis jedis = jedisPool.getResource();
        //标记一个事务块,开启事务
        Transaction transaction = jedis.multi();
        try {
            transaction.set("name1","江先进");
//            int n = 10/0;
            transaction.set("name2","张硕");
            //执行事务
            transaction.exec();
        }catch (Exception e){
            //取消事务
            transaction.discard();
            e.printStackTrace();
        }


redis提供了简单的事务功能,将一组需要一起执行的命令放到 multi 和exec两个命令之间。multi命令代表事务开始,exec命令代表事务结束,另外discard命令是回滚
回滚机制上,redis只能对基本语法错误进行判断,运行时错误无法回滚

6.redis的过期策略及内存淘汰机制

7.缓存穿透、缓存击穿、缓存雪崩

1.缓存穿透:数据库和redis都不存在

解决方案

  • 1.参数校验,屏蔽非法参数
  • 2.数据库查询为空,可缓存一个空值或默认值
    1. 使用布隆过滤器快速判断数据是否存在

2.缓存击穿:单个key没有或过期,同一时间查询这同一条数据并发量过多

解决

  • 热点数据用不过期,或者通过异步线程在每次热点数据快要过期时,进行续期
  • 使用互斥锁,避免大量请求同时查询数据库
  • 熔断、降级、防止系统崩溃
  • 还可以考虑对重要的热点数据进行多级缓存

3.缓存雪崩:同一时间,缓存大面积失效

原因

1.redis失效、宕机(故障)

  • 搭建Redis集群,主从架构
  • RDB持久化、IOF持久化
  • 加入缓存组件:EHCache,搭建多级缓存(容易高并发的数据存入)
  • 加入限流组件:hystrix,超过一定流量后,增加请求限制(保护数据处理层)

2、Redis大量key的ttl过期
ttl(过期时间)岔开,增加随机值,避免同一时间全部失效。

  • 热点数据永不过期,或者通过异步线程在每次热点数据快要过期时,进行续期
  • 数据的过期时间不要全一致,设为一定范围内的随机时间
  • 并发量不高,可加入队列或者锁,限制同一时间访问数据库的阈值
  • 分布式部署,将热点数据打散分不到多个节点
  • 如果是缓存中间件宕机了,需要尽可能保证其高可用性,可以搭建redis集群,提前做好报警机制

8.什么是bigkey,会有什么影响

key对应的value所占内存空间较大

比如字符串类型:单个value值特别大,一般认为超过10kb就是bigkey,和具体的ops相关

非字符串类型:哈希、列表、集合、有序集合,体现在元素个数过多

危害

  • 内存空间不均匀
  • 超时堵塞:单线程操作bigkey比较耗时
  • 网络拥塞:每次获取bigkey产生的网络流量较大

例如:一个bigkey为1MB,每秒访问为1000,则每秒产生1000MB的流量,普通千兆网(按照字节算是128MB/s)的服务器是灭顶之灾,而且服务器通常会采用单机多实例的方式来部署,可能会对其他实例造成影响。

解决方案:value拆分

redis如何解决key冲突

  • 1.业务隔离
  • 2.key的设计:业务模块+系统名称+关键(id),针对用户可以加入(userid)
  • 3.分布式锁:多客户端并发写入key
  • 4.时间戳:key拼接时间戳,根据时间戳保证多个客户端的业务执行顺序

redis怎么提高命中率

  • 1、提前加载
  • 2、增加缓存的存储空间,增加缓存的数据
  • 3、调整缓存的存储类型
    例:对象通过Hash存储,而不用String。
    根据业务做适当调整。
  • 4、调整缓存的存储类型
    • 定时任务更新
    • MySQL通过检测binlog,将消息推送到Redis,更新缓存
    • 通过Mq,业务更新修改数据时,通过MQ发送消息,消费更新缓存

redis持久化方式有哪些方式,有什么区别?

持久化:将数据写入磁盘,,避免因进程退出而造成 的数据丢失,下次重启时通过持久化文件恢复数据。

RDB(快照)

通过快照(内存中数据在某一时刻的状态记录)的方式实现持久化,根据快照的触发条件,将内存的快照写入磁盘,以二进制的压缩文件进行存储。
缺点:每隔一段时间触发持久化,数据安全性低

AOF(独立日志)

以独立日志的方式记录每次写的命令,重启时重新执行aof文件中的命令恢复数据
AOF重写机制:AOF文件的大小达到某个阈值时,会将其中指令进行压缩。(如果有对于某个key多次的变更指令,则仅保留最新的数据指令)。
*优化
因为AOF重写过程中需要读取当前内存中所有键值数据,性能较低,redis将其放在一个后台子线程中完成。
为了避免重写过程中出现数据变动,主进程的数据变更需要追加到AOF重写缓冲区中,等到AOF重写完成后,再把AOF重写换乘区里面的内容追加到新的AOF文件中。
缺点:AOF文件可能过大,性能较差

如果执行bgrewriteaof命令,将内存中已有的数据以二进制格式存放在AOF文件中(模拟RDB),后续命令亦然采用AOF追加方式。

生产环境中一般采用两种持久化机制混合使用。

将内存中数据快照存储在AOF文件中(模拟RDB),后续再以AOF追加方式。

如果仅作为缓存使用,可以承受几分钟数据丢失,可以使用RDB,对主程序性能影响最小
redis持久化

如何保证缓存与数据库双写一致性:

1.新增数据类

新增数据时,数据会直接写入数据库,不用对缓存做任何操作;此时缓存没有新增数据,而数据库中是最新值。

2.更新缓存类

1.先删除缓存,后更新db

  • 先淘汰缓存-》再写数据库—〉休眠1秒,再次淘汰缓存
    延迟双删可以有效避免缓存不一致问题
    以下是伪代码实现延迟双删
redis.delkey(x)
db.update(x)
Thread.sleep(n)
redis.delkey(x)

3.读取binlog日志:

异步删除,更新缓存

  • 可以使用canal将binlog日志采集发送mq队列中
  • 通过ack机制确认处理这条更新消息,删除缓存,保证数据一致性

redis集群方案

redis常见性能问题和解决方案

1、持久化 性能问题
早期仅支持全量复制->部分复制(一台机器性能开销过大)

因此开始配置主从 :主节点不再做持久化而是交给从节点来做

2、数据比较重要,开启AOF。策略最好配置每秒同步。
3、主从复制 流畅,建议同一个局域网内操作,负责网络开销过大
4、尽量避免主库压力过大,增加从库
5、主从复制 尽量不要使用网状结构、线性结构

什么情况下可能会导致redis阻塞

  • 客户端阻塞:命令执行时间过长: keys* Hgetall smembers 时间复杂度O(N)
  • BigKey删除:需要释放大量占用内存 zset(100万的元素 删除大概需要2s)
  • 清空库:flushdb
  • AOF日志同步写,记录AOF日志
  • 从库 加载RDB文件
  • redis尽量部署独立的服务器中

线上redis响应慢处理思路:

  • 1、紧急处理方案,扩容
  • 2、生产环境查看Redis内存使用率,分析一定时间段内key数量变化
    分析是否是大量数据未设置过期时间,或者是因为新版本迭代引起
  • 3、清除bigkey,优化生成bigkey的代码块,调整未设置过期时间的代码块
  • 4、根据业务场景调整淘汰策略

如何保证redis高可用:

主从模式:

  • 部署多台redis服务器,主从复制保证数据副本一致,主库通过rdb文件发送从库实现复制
  • 主从采用读写分离,主库写操作,从库读操作
  • 主库宕机,手动切换从库称为主库,通知应用方更新主节点地址

哨兵模式

作用

  • 监控:周期性ping主从库,检测是否挂了,标记下线状态
  • 自动选主切换:多个从库按照一定规则选作主库
  • 通知:选出主库,把主库信息发送给其他从库及应用方,重新建立连接

由一个或多个哨兵实例组成哨兵系统,监控其他Redis节点的同时,哨兵实例之间也互相监控。

哨兵之间通过发布订阅机制组成集群。一主多从

缺点:无法实现在线扩容,并发压力受限于单个服务器的资源配置。

26.3 Redis Cluster
哨兵模式解决了自动切换主从的问题,但是没有解决在线扩容的问题。

本质:Redis Cluster实现了Redis的分布式存储,每个节点存储不同的数据,实现数据分片。

引入Slot槽实现数据分片,每个节点分配一个Slot区间,当我们存取Key的时候,Redis根据key计算得到Slot值,找到对应的节点进行读写。多主多从。

布隆过滤器

布隆过滤器可以应对缓存穿透问题
数据结构:一个很长的二进制向量和一组Hash映射函数组成。

作用:检索一个元素是否在一个集合中,空间查询效率比一般的算法要好的多。

缺点:有一定误识别率和删除困难。

原理:集合A中有n个元素,利用K个哈希散列函数,将A中每个元素映射到一个长度为a位的数组B中不同位置上。这些位置上的二进制数均设置为1。经过这个K个哈希散列函数映射后,发现其k个位置上的二进制数全部为1,这个元素很可能属于集合A。

Redis的理解

  • 本质:基于Key-Value存储结构的非关系型数据库
  • 数据类型:提供5种基本数据类型,String、set、zset、list、Map。
  • 性能:基于内存存储,并且在数据结构上做了大量优化,IO性能较好。
  • 作用:作为应用与数据库之间的分布式缓存组件。
  • 高可用:提供了主从复制、哨兵、以及集群方式实现高可用,集群中通过hash槽的方式实现了数据分片,进一步提升了性能。

原文链接:https://blog.csdn.net/Zyw907155124/article/details/129830935

标签:缓存,redis,Redis,命令,数据,节点
From: https://www.cnblogs.com/Skyvswfq/p/18159099

相关文章

  • Redis淘汰策略
    Redis过期策略有几种?Redis中提供八种过期策略,默认是noeviction,即不删除任何数据,当内存不足时会直接报错。可以在Redis的配置文件中进行设置。noeviction:不淘汰任何key,但是内存满时不允许写入新数据,默认就是这种策略。volatile-ttl:对设置了TTL的key,比较key的剩余TTL值,TTL越......
  • Redis场景
    redis应用场景Redis在缓存和队列方面有着广泛的应用场景,下面详细介绍一下:缓存应用场景:页面缓存:在Web应用中,Redis可以用作页面缓存,存储页面渲染结果,以减轻数据库的压力,提高页面响应速度。当用户请求某个页面时,首先检查Redis中是否存在该页面的缓存,如果存在则直接返回缓......
  • redis安装及使用
    Redis与传统数据库的一个主要区别在于,Redis把所有数据都存储在内存中,而传统数据库通常只会把数据的索引存储在内存中,并将实际的数据存储在硬盘中。为了满足不同的持久化需求,Redis提供了RDB持久化、AOF持久化和RDB-AOF混合持久化等多种持久化方式以供用户选择。如果用户有需要,也......
  • redis使用
    Pythonredis使用介绍|菜鸟教程(runoob.com)Python操作Redis,你要的都在这了!-John-Python-博客园(cnblogs.com)redis基本命令Stringset(name,value,ex=None,px=None,nx=False,xx=False)在Redis中设置值,默认,不存在则创建,存在则修改。参数:ex-过期时间(秒......
  • Redis过期策略
    在Redis中提供了两种数据过期删除策略:惰性删除:在设置该key过期时间后,我们不去管它。当需要该key时,我们会检查其是否过期,如果过期,就删除它;反之,返回该key。定期删除:每隔一段时间,我们会对一些key进行检查,删除其中过期的key。定期清理有两种模式:SLOW模式:使用定时任务,执行频率......
  • Redis 面试知识点
    1、Redis缓存数据库一致性采用最终一致性,而不是采用强一致性,强一致性会导致系统吞吐量变差;采用双删除的策略,第二次删除,采用延迟删除;推荐采用,先操作数据库,直接删除缓存的方式;删除失败的情况,采用异步方式,重试操作;读取binlog异步删除,使用开源框架canal,监听canal......
  • Redis缓存穿透,击穿和雪崩
    缓存穿透缓存穿透是指查询一个一定不存在的数据,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到DB去查询,可能导致DB挂掉。这种情况大概率是遭到了攻击。解决方案的话,我们通常都会用布隆过滤器来解决它。布隆过滤器主要是用于检索一个元素是否在......
  • Redis持久化
    redis做为缓存,数据的持久化是怎么做的?在Redis中提供了两种数据持久化的方式:RDBAOF这两种持久化方式有什么区别呢?RDB是一个快照文件,它是把redis内存存储的数据写到磁盘上,当redis实例宕机恢复数据的时候,方便从RDB的快照文件中恢复数据。AOF的含义是追加文件,当redis操作写......
  • Redis进阶 -
    之前已经总结了Redis的基础使用  springboot3+vue3(八)Redis基础使用--登录优化Redis进阶主要总结一下以下知识点:Redis持久化Redis主从Redis哨兵Redis分片集群 Redis单节点问题,以及解决方案:1、数据丢失问题(Redis是内存存储,服务器重启可能会丢失数据。)-----解决......
  • redis ----window本地服务
    注册为本地服务进入Redis安装目录,命令格式如下:--service-install服务安装命令--service-name指定服务名--port指定端口运行如下命令:注意:需要在redis.windows.conf配置文件中修改port为6379(默认不用修改)注册成功,查询服务列表,redis服务注册成功,如下图图:2.2启动本地服务服务注......