redis篇

点赞再看,养成习惯,微信搜索「 小大白日志」关注这个搬砖人。

文章不定期同步公众号,还有各种一线大厂面试原题、我的学习系列笔记。

数据结构 应用场景 string 普通的键值对存储 list(元素可重复) 粉丝列表、文章评论 set(元素不重复) 获取交集、并集的用户数据 zset(元素不重复) 获取排名靠前的用户 hash 存储用户属性后支持快速修改

数据结构 应用场景 hyperLogLog 基数统计,如统计一个网站首页一天的用户访问量(一个用户每天访问多次只能算一次访问) geo 摇一摇、查看附近的人 Pub/Sub发布订阅 订阅频道

redis4.0以上提供了module,用户可以根据自己的需求扩展redis的功能,比如布隆过滤器

如果大量的key在同一个时间点过期,则在这个时间点redis可能会出现卡顿,严重的话缓存雪崩,在给key设置失效时间后,可以再添加一个随机失效时间使所有key的失效时间不集中在某个时间点(电商页面需要使用定时任务定时刷新redsi缓存)

  • aof和rdb都是把缓存中的数据存入磁盘,分别形成.aof和.rdb文件
  • rdb是间隔一定时间就把redsi缓存里面的数据以镜像的方式存入磁盘,在下一次持久化之前如果发生故障则会丢失最新的缓存数据,比较适合对数据完整性要求不严格的情况;rdb方式会使用一个fork子进程持久化数据,而主进程则保持处理正常命令,所以主进程不会进行I/O操作
  • aof有always/everysec/no三种方式实时地将redis命令持久化到磁盘中(每次都在文件内容后面增加新内容),所有aof文件肯定比rdb文件大,恢复数据时rdb比aof的快
  • 建议优先使用aof持久化,最好同时开启两种持久化方式,如果同时开启则redis默认优先使用aof方式持久化

  • 使用一致性哈希算法:在分布式缓存环境中,简单的哈希算法将key被保存在【key.hashcode()%N】中,N=服务器数=redis节点数,但是扩容增加服务器时原有节点的映射关系就变了;而一致性哈希算法是将【0~ 2^(31-1)】 个位置看做一个环,所有key和所有节点都对将 2^(31-1) 进行求余从而确定其在 2^(31-1)哪个位置,即【key.hashcode()% 2^(31-1)】、节点可以用IP或其他因子如【节点IP% 2^(31-1) 】,确定key在2^(31-1)这个环空间的位置后,顺时针方向找”最近的节点所在环中的位置”,该节点便是这个key的存储位置;

  • 一致性哈希算法产生的问题:如果redis集群中节点太少,就会导致节点分布在环中的位置不均匀,从而导致key不均匀地分布在redis节点缓存中,进而导致某些节点数据压力过大,解决:在节点数量少的时候,可以给每个节点=真实节点设置同等数量的’虚拟节点’,这些虚拟节点也对 2^(31-1)求余,当某个key落在虚拟节点的时候实际上是落在它的真实节点上,如下图,问题解决!

redis篇
* 一致性哈希算法的思想如何在redis集群中使用:redis没有使用一致性哈希算法,而是引入了它的概念=>在redis集群中设置16384个槽(相当于这个环有16384个位置),这16384个槽均匀地分布在N台服务器上(即N个redis节点,每个节点所处的环位置就是该节点’最大的槽号’),key会被保存在第【key.hashcode()%16384】=【CRC16(key)%16384】号槽中,离该key槽号有另外一个槽号=某个节点A的最大槽号,则该key就存放在这个A节点中;当需要增加1个redis节点扩容时,把原所有节点的一部分槽分给新节点即可;当需要减少1个节点缩容时,把那个节点的槽移到其他节点即可
  • 定时删除:给每个key设置一个定时器,到点就删除对应的key-value,缺点是定时器会消耗大量的CPU资源
  • 惰性删除:使用到这个key的时候去检查是否过期,若过期就删除,缺点是只有在用到的时候才会去检查删除内存中的数据,若没用到且过期的数据则一直占据着内存比较耗费内存
  • 定期删除:设置一定的时间周期,选择性地扫描redis内存中的expire字典(内含ekey-evalue,expire的ekey是指向redis中key的指针,evalue是该key的过期时间),过期则删除,注意是扫描部分key而非全部扫描

redis默认使用后两种删除策略

redis的过期淘汰策略是指定key-value过期时怎么处理,而redis的内存淘汰策略是指在插入新key-value时,剩余空间不足则如何处理,处理措施分两种情况:

  • 对于所有设置了过期时间的key:
  • 删除最近最少使用的key(LRU算法,常用)
  • 随机删除某个key
  • 删除存在时间最长的那个key
  • 对于所有的key-value,不管有没有设置过期时间:
  • 报错
  • 删除最近最少使用的key(LRU算法,常用)
  • 随机删除某个key

利用好五种常用的数据结构类型;复杂的存储尽量用hash结构,因为hash占空间少

redis事务中可含多条命令,每条命令都是原子性的、按顺序执行的;每个事务互不影响相互隔离;事务中某条命令执行失败,其他命令仍可以执行成功(故事务不保证原子性:要么全部执行成功要么全部失败),且redis事务不提供回滚功能

主要有三种:主从模式、哨兵sentinel模式、redis-cluster模式

  • 哨兵模式
  • sentinel可以发消息通知:当redis集群中某个节点下线了,发消息给管理员
  • sentinel可以对redis主节点”故障转移”:sentinal进程会监听主从节点是否正常工作,当大部分sentinel节点都认为主节点挂掉时,会在从节点中重新选举主节点:sentinal集群可能会有多个sentinal,但这些sentinal的信息会被保存为一份相同的列表,列表再被各个sentinal各自保存,重新选举时,列表中排第一位的sentinal开始对主节点执行”故障转移”(转移原主节点的数据到新主节点),执行失败再由第二位sentinal执行。当从节点被选为新的主节点后,此时”故障转移”已经算是成功了,然后sentinal会把旧主节点的信息写进新主节点,然后再广播新主节点的信息
  • sentinel集群+redis集群保证高可用:至少是3个sentinel节点才能组成sentinel集群,且sentinel集群+redis集群只保证高可用行,不保证数据是否丢失
  • redis cluster模式
  • redis的cluster模型:允许将数据按照约定的规则分开存储在多个redis服务器机器上,避免redis单机存储容量过小
  • redis集群会有16384个散列槽,当增加集群中的redis节点时,只需将部分散列槽移动到新redis节点当减少redis节点时,把散列槽移到其他节点即可往redis集群中添加(key,value)时,由算法=【CRC16(key)%16384】决定将key放到哪个散列槽取出key时也用同样的算法取出;
  • redis集群中保存key-value时可能会发送到任一redis节点,该节点会将key-value发到正确的节点上;读取key时,若key不在本节点上,则本节点执行转向命令转向正确的节点

将所有key-value分布在不同的节点上,这样能充分利用多台计算机的内存和CPU处理能力;

缺点:

  • 存在于不同节点的key不能做set交集等操作;
  • 需要同时处理每个节点的aof/rdb文件

分区的两种方式:

  • 客户端分区,在用户的客户端就已经决定好把key保存到哪个节点上
  • 查询路由分区,把key请求发到任一节点上,再由该节点决定转发到哪个最终节点保存

红锁=redis官方提供的一种实现分布式锁的算法,它保证分布式环境下只有一个客户端能拿到某共享资源的锁,且永远不会因为宕机或其他原因等造成死锁

当某个节点发生故障从而影响到核心功能服务,仍要提供正常服务给用户,即使提供的是有损的服务。常见的如某个redis出现故障,为防止大量请求去到数据库而导致雪崩,可以直接返回默认值。

  • redis支持复杂的数据结构(常见有5种数据类型),而memcached保存的所有值都是简单的string
  • redis支持持久化到硬盘,而memcached数据只能存在于内存中,故每次启动应用需要重新按需加载数据到memcached中
  • 处理小数据量时redis快,大数据量时memcached快
    redis篇

有些数据需要同时写入数据库和写入缓存,应尽量保证数据库和缓存的双写一致性:如果先写redis缓存,若redis写成功而数据库失败则出现脏读->必须先写数据库再写redis缓存,若数据库写成功而redis写入失败,则在下次读取缓存值的时候,先读数据库再加载到缓存中。

OK,如果文章哪里有错误或不足,欢迎各位留言。

创作不易,各位的「 三连」是二少创作的最大动力!我们下期见!

Original: https://www.cnblogs.com/mofes/p/15101148.html
Author: 明天喝可乐
Title: redis篇

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/589753/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Android连载39-简析HAL、拨号盘

    一、简析HAL结构 HAL是一个位于操作系统和驱动程序之上,运行在用户空间中的服务程序。 目的:对上层应用提供一个统一的查询硬件设备的接口。 好处:简化了应用程序查询硬件的逻辑 注…

    Java 2023年6月13日
    079
  • screw-数据库文档生成器

    文档地址:https://gitee.com/leshalv/screw cn.smallbun.screw screw-core 1.0.5 import cn.smallbun…

    Java 2023年6月9日
    082
  • springboot 整合 Shiro 配置类

    ckage org.fh.config; import org.apache.shiro.cache.ehcache.EhCacheManager; import org.apac…

    Java 2023年6月8日
    080
  • 一个JDBC封装工具类

    前言 在使用Java操作MySQL数据库的时候,会使用到JDBC驱动,但是在每次连接并使时都需要创建一堆的类和相关参数,还是有点麻烦的。在这里有一个封装好的JDBC工具类,里面包含…

    Java 2023年6月8日
    068
  • [游戏引擎中文版]YU-RIS 4.5 最新中文支持版

    今天给大家带来一个很重要的引擎——YU-RIS 相对于复杂的krkr2,YU-RIS要可爱的多。 为什么我要说她很重要呢? 我看过不下10篇,日本GAL引擎 介绍 基本每一篇都会介…

    Java 2023年5月29日
    090
  • 入学体检—二甲及二甲以上医院

    终于可以去一所一本院校再读两年书。于2022年4月6日体检。现将体检过程分享给网友。 先是在学校官网下载体检表,第二天去的一家三甲医院。 在哔哩哔哩上看了一眼体检注意事项。 如果有…

    Java 2023年6月5日
    063
  • RuoYi(若依)前后端分离版本,windows下部署(nginx)

    上一篇用了tomcat部署(https://blog.csdn.net/yueyekkx/article/details/105491363),还是觉得nginx是王道话不多说开始…

    Java 2023年5月30日
    072
  • 20220812-Java内部类

    跟老韩学完了java面向对象的高级篇,老师提到了卖油翁和老黄牛的故事,在学习Java的路上,借以自勉,”我亦无他,唯手熟尔”,天道酬勤,长路漫漫,少年加油,…

    Java 2023年6月15日
    083
  • CompletableFuture的入门

    runAsync 和 supplyAsync runAsync接受一个Runable的实现,无返回值 CompletableFuture.runAsync(()->Syste…

    Java 2023年6月9日
    079
  • 消息的种类与消息队列的处理方式

    消息的种类 1.1 按照发送的特点分 同步消息 异步消息 单向消息 举例: 同步消息 我去小吃店要了一套煎饼果子,在门口等了十分钟,煎饼果子好了老板告诉我让我取餐。 异步消息 我去…

    Java 2023年6月14日
    092
  • 队列小哥哥喊你来排队了~(自带循环的那种)

    大家好,我是melo,一名大二上软件工程在读生,经历了一年的摸滚,现在已经在工作室里边准备开发后台项目啦。不过这篇文章呢,还是想跟大家聊一聊数据结构与算法,学校也是大二上才开设了数…

    Java 2023年6月5日
    0104
  • SpringCloudAlibaba项目之Ribbon负载均衡

    SpringCloudAlibaba随笔目录 一、SpringCloudAlibaba项目之父工程搭建 二、 SpringCloudAlibaba项目之Nacos搭建及服务注册 三…

    Java 2023年6月5日
    099
  • 通过Nginx获取用户真实IP

    nginx配置 如上面配置,接口需要使用的时候获取X-real-ip就可以,但是经过测试以后,发现X-real-ip并不是真实的用户IP,而是Nginx代理服务器的IP,原因就是经…

    Java 2023年5月30日
    093
  • nginx刷新显示404

    1、web单页面开发模式,只有一个index.html入口,其他路径是前端路由去跳转的,nginx没有对应这个路径,所以就会报404了。 2、增加try_files $uri $u…

    Java 2023年5月30日
    091
  • 全量同步Elasticsearch方案之Canal

    一、前言 Canal 是阿里的一款开源项目,纯 Java 开发。基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了 MySQL(也支持 mariaDB)。 Ca…

    Java 2023年6月6日
    082
  • IDEA中Git的使用

    Git在IDEA中的使用 JAVA技术交流群:737698533 创建和导入 创建一个新项目到Gitee上 首先创建一个仓库,勾选上初始化 获取新创建仓库的路径 然后随便在一个文件…

    Java 2023年6月6日
    073
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球