当前位置: 首页 > 科技观察

Redis漫谈(一):构建知识图谱_1

时间:2023-03-18 19:59:27 科技观察

场景:Redis面试(图片来自网络)面试官:我看到你的简历上说你精通Redis的使用,请问Redis是用来做什么的?小王:(心里庆幸,Redis不就是个缓存吗?)Redis主要是作为缓存,通过内存高效存储非持久化数据。面试官:Redis可以做持久化存储吗?小王:嗯……应该可以吧……面试官:Redis是如何进行持久化操作的?小王:嗯……不太清楚。面试官:Redis的内存淘汰机制有哪些?小王:嗯……不太了解。面试官:我们还可以用Redis做什么?使用了哪些Redis指令?小王:只知道Redis还行做分布式锁,消息队列...面试官:好吧,我们进入下一个话题...思考:很明显,小王在面试中关于Redis的表现和回答肯定是失败了.Redis是我们日常工作中都会用到的东西。为什么到了面试就成了失物招领?作为开发者,我们习惯使用大神们封装好的东西,这样可以保证我们可以更专注于业务开发,但是不知道这些常用工具的底层实现是怎样的,所以虽然平时用起来得心应手,到了面试的时候还是不能让面试官眼前一亮。本文总结了Redis的一些知识点,有原理也有应用,希望对大家有所帮助。什么是RedisREmoteDIctionaryServer(Redis)是由SalvatoreSanfilippo编写的键值存储系统。Redis是开源的,用ANSI和C语言编写,遵守BSD协议,支持网络,可以是基于内存的也可以是持久化的,日志型,Key-Value数据库,提供多种语言的API。这里我引用Redis教程中对Redis的描述,官方的但是标准的。一种日志类型的Key-Value数据库,可以是基于内存的或持久的。我认为这个描述非常贴切和全面。一、Redis的行业现状Redis是互联网技术领域应用最为广泛的存储中间件。因其超高性能、多方位的应用能力、丰富完善的客户端支持,在存储上独树一帜,广受好评,尤其是性能。而读取速度已经成为该领域最受欢迎的中间件。基本上每个软件公司都会用到Redis,包括很多大型互联网公司,比如京东、阿里、腾讯、github等,因此Redis也成为了后端开发者不可或缺的技能。2.知识图谱在我看来,学习每一项技术,都需要有清晰的脉络和结构,否则不知道自己知道多少,还有多少没有学到。就像一本书,如果没有目录,它就失去了灵魂。因此,我尝试总结了Redis的知识图谱,也就是脑图。如下图所示,知识点可能不完整,以后会不断更新补充。本系列文章的知识点也会与这张脑图基本一致。本文首先介绍Redis的基础知识,后续文章将详细介绍Redis的数据结构、应用、持久化等方面。Redis的优点1、速度快作为缓存工具,Redis最广为人知的特点就是速度快。它有多快?Redis单机qps(每秒并发数)可达11万次/s,写入速度81000次/s。那么,为什么Redis这么快呢?大部分请求都是纯内存操作,速度非常快;许多搜索操作非常快的数据结构用于数据存储,Redis中的数据结构是专门设计的。比如HashMap,查找和插入的时间复杂度是O(1);使用单线程避免了不必要的上下文切换和竞争条件,也没有多进程或多线程切换导致的CPU消耗。对于各种锁问题,没有加锁和释放操作,没有可能出现的死锁带来的性能消耗;使用非阻塞I/O多路复用机制。2、丰富的数据类型Redis有五种常用的数据类型:String、List、Hash、set、zset。每种数据类型都有自己的用途。3、原子性,支持事务Redis支持事务,所有操作都是原子的。同时,Redis还支持合并后几个操作的原子执行。4、丰富的特性Redis具有丰富的特性,比如可以作为分布式锁使用;它可以持久化数据;它可以用作消息队列、排行榜、计数器;它还支持发布/订阅、通知、密钥过期等。当我们想使用中间件解决实际问题时,Redis总能发挥它的作用。Redis和Memcache的比较Memcache和Redis都是优秀的高性能内存数据库。一般说起Redis,我们都会将Memcache和Redis进行比较。(为什么要做对比?当然是为了展示Redis有多好,没有对比就没有伤害~)对比的方面包括:(1)存储方式Memcache将所有数据存储在内存中,并且掉电会挂掉,无法实现数据持久化,数据不能超过内存大小。Redis有一部分数据存储在硬盘上,可以实现数据持久化。(2)数据支持类型Memcache支持的数据类型比较简单,只支持String类型的数据结构。Redis拥有丰富的数据类型,包括:String、List、Hash、Set、Zset。(3)所使用的底层模型在与客户端通信的底层实现和应用协议上有所不同。Redis直接自己搭建了VM机制,因为一般的系统调用系统函数都会浪费一定的时间去移动和请求。(4)存储值大小Redis可以存储1GB,而memcache只有1MB。看到这里,是不是觉得Redis特别好,都是优点?其实Redis还是有很多不足的。我们通常如何克服这些缺点呢?Redis的问题及解决方案1.缓存数据库双写一致性问题问题:一致性问题是分布式系统中非常普遍的问题。一致性一般分为两种:强一致性和最终一致性。当我们要满足强一致性的时候,Redis不可能是无懈可击的,因为数据库和缓存是双写的,肯定会出现不一致的情况。Redis只能保证最终的一致性。解决方案:如何保证最终的一致性?可以为缓存设置一定的过期时间,缓存过期后会自动查询数据库,保证数据库和缓存的一致性。如果没有设置过期时间,首先要选择正确的更新策略:先更新数据库,再删除缓存。但是我们删除缓存的时候也可能会出现一些问题,所以我们需要把要删除的缓存的key放在消息队列中,不断重试,直到删除成功。2.缓存雪崩问题问题:我们应该都在电影里看过雪崩,开始的时候很平静,然后瞬间就开始崩溃,破坏力很大。这里也是一样。我们在执行代码的时候,我们把很多缓存的有效时间设置成相同的,那么这些缓存会同时生效,然后它们会重新访问数据库更新数据,这样会导致数据库过多连接和压力过大。和崩溃。解决方法:在设置缓存过期时间的时候加入一个随机值。设置双缓存,缓存1设置缓存时间,缓存2不设置,1过期后直接返回缓存2,并启动一个进程更新缓存1和2。3.缓存穿透问题问题:缓存穿透指的是一些异常用户(黑客)故意请求缓存中不存在的数据,导致所有请求都集中在数据库上,导致数据库连接异常。解决方案:使用互斥量。当缓存失效时,不能直接访问数据库,但必须先获取锁才能请求数据库。如果没有获得锁,它会休眠一段时间,然后再次尝试。采用异步更新策略。不管key有没有值,直接返回。value值中维护了一个缓存过期时间。如果缓存过期,则异步启动一个线程来读取数据库并更新缓存。需要进行缓存预热(在项目启动前加载缓存)操作。提供拦截机制,可以快速判断请求是否合法。例如,Bloomfilter用于内部维护一系列合法有效的key,以快速判断请求中携带的Key是否合法有效。如果无效,直接返回。4、缓存并发竞争问题:缓存并发竞争问题主要出现在多个线程设置一个key时,此时会出现数据不一致的情况。比如在Redis中,我们存储了一个value,key为amount,value为100,两个线程同时给value加100,然后更新。正确的结果应该是300。但是当两个线程拿到这个值的时候,都是100,结果是200,这就导致了缓存的并发竞争问题。解决方案如果多线程操作没有顺序要求,我们可以设置一个分布式锁,然后多个线程竞争锁,谁先抢到锁就可以先执行。这个分布式锁可以用zookeeper或者Redis本身来实现。可以使用Redis的incr命令。当我们的多线程操作需要顺序时,我们可以建立一个消息队列,将需要的操作加入到消息队列中,严格按照队列的顺序执行命令。RedisExpirationPolicyRedis随着数据的增加,内存使用率会不断增加。我们原以为有些key到了设定的删除时间就会被删除,但是时间一到,内存使用率还是很高。为什么是这样?Redis采用了定时删除和惰性删除的内存淘汰机制。1.定期删除定期删除和定期删除有区别:定期删除必须严格按照设定的时间来删除缓存,这就需要我们设置一个定时器不断轮询所有的key来决定是否删除。但是在这种情况下,CPU资源会被大量占用,资源利用率会变低。所以我们选择使用定期删除。定期删除的时间由我们决定。我们可以每100毫秒检查一次,但我们仍然无法检查所有缓存。Redis仍然会卡住。我们只能随机检查一些缓存,但是有些缓存将无法在指定的时间内。删除。这就是延迟删除派上用场的地方。2.懒删举个简单的例子:我上中学的时候,平时功课太多,做不完。老师说下节课要讲这篇论文。你们都做完了吗?其实很多人都没有做完,下节课前补上是很有必要的。惰性删除也是如此。我们的价值应该消失了,但它仍然存在。当你想获取key的时候,发现key应该已经过期了,赶紧删除,然后返回一个'没有这个值,已经过期了!'。既然有了定时删除+惰性删除的过期策略,是不是就可以高枕无忧了?不是这样的,如果key没有被访问过,就会一直不通,这就需要我们的内存淘汰机制起来。Redis的内存淘汰机制一般有6种,如下图所示:那么我们如何配置Redis的内存淘汰机制呢?在Redis.conf中,我们可以配置#maxmemory-policyallkeys-lru查看Redis的知识图谱,我们可以发现Redis有这么多的知识点可以通过对比学习;然后我们分析了Redis的优缺点,知道了它高效的基于内存的读写速度和丰富的数据类型,同时也分析了Redis应该如何处理数据一致性、缓存穿透、缓存雪崩等问题;我们了解了Redis的过期策略和缓存淘汰机制。相信大家对Redis已经有了一定的了解。在下一篇文章中,我们将分析Redis的数据结构,每种数据类型是如何实现的,以及对应的命令是什么。【本文为栏目机构易新科技原创文章,微信公众号“易新科技(id:CE_TECH)”点击此处查看作者更多好文