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

今天刚了解到Redis有7种数据类型...

时间:2023-03-18 17:05:23 科技观察

【.com原稿】面试官:Redis有哪些数据类型?存储原理是什么?它们适用于哪些应用场景?生动吗?是Redis关于数据类型的连续3道面试题,是除了“Redis持久化”之外最常见的Redis考题。图片来自Pexels。但是不管面试官的问题还是网上的答案,基本都是错的!本文将源码剖析给读者,深入浅出,过目不忘。查谷歌不同意见一:Redis的5种类型支持5种数据:String(字符串)List(列表)Set(集合)SortedSet(有序集)Hash(散列)这个也是业界普遍认可的,最常见的答案。关于这5种的详细解释,网上已经铺天盖地,这里不打算再赘述,请读者自行查阅。语句2:6种类型包括“语句1”中的5种类型,还包括:HyperLogLog(base)。即:String(字符串)、List(列表)、Set(集合)、SortedSet(有序集合)、Hash(散列)和HyperLogLog(基数)。语句3:9种类型包括“语句2”中的6种类型,还包括:Bitmap(位集)、Geospatial(地理空间索引)、Streams(流信息)。即:String(字符串)、List(列表)、Set(集合)、SortedSet(有序集合)、Hash(散列)、HyperLogLog(基数)、Bitmap(位集合)、Geospatial(地理空间索引)、Streams(流信息)共9种。还有一种说法是不包含Streams(流信息),但是包含BloomFilter(布隆过滤器)。这个不重要,但是据说有9种,没有10种。从官网找答案英文官网:https://redis.io/,中文官网:http://www.redis.cn/,首页如下:请注意这句话:Redis提供数据结构,例如字符串、散列、列表、集合、带范围查询的排序集合、位图、hyperloglogs、地理空间索引和流。很明显,官网提到Redis支持的数据类型有9种。与上述“论点三”基本一致。另外值得注意的是,中文官网并没有提到Stream,就是少了一句话。因为Stream是2018年10月5.0版本推出的,但是中文官网至今没有更新,是一个很明显的文案bug(不知道反馈采纳后有没有bonus)。那么问题解决了吗?还没有!问题才刚刚开始。具体问题具体分析为什么“论点1:5种类型”被业界普遍认可我们来看看Redis各种高级功能类型的引入版本,如下表所示:显然,原因是那这些功能在后续版本中是相继推出的,这5种数据类型是最经典的5种类型,因此代代相传已久。再来看看Redis各个大版本的发布时间,如下表所示:也就是说,业界对“五种数据类型”的认识已有10年,认知错误的时间为10年。“陈述3:9种类型”是否正确?要回答这个问题,首先要了解如何通过typeKEY_NAME命令查看Redis的数据类型。另外,具体的编码结构可以通过objectencodingKEY_NAME命令查看,这里只是简单提及,不在本文讨论范围之内。①Stringlocalhost:6379>setstr:helloworldOKlocalhost:6379>getstr:hello"world"localhost:6379>typestr:hellostring②Bitmaplocalhost:6379>setbitstr:a11(整数)0localhost:6379>setbitstr:a21(整数)0localhost:6379>setbitstr:a71(integer)0localhost:6379>getstr:a"a"localhost:6379>typestr:astring很明显,Bitmap底层也是用String实现的,赋值的每一位对应ASCII码的二进制位。③HyperLogLog127.0.0.1:6379>PFADDhyperLogLog:db"redis"(整数)1127.0.0.1:6379>PFADDhyperLogLog:db"mongodb"(整数)1127.0.0.1:6379>PFADDhyperLogLog:db"mysql"(整数)1127.0.0.1:6379>PFCOUNThyperLogLog:db(整数)3127.0.0.1:6379>gethyperLogLog:db"HYLL\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00H\x91\x80\\g\x84[\x03"127.0.0.1:6379>typehyperLogLog:dbstring很明显,HyperLogLog的底层也是用String实现的。与其说HyperLogLog是一个单独的数据类型,不如说它是一个封装了String数据类型API的应用程序。.④总结其他几种高级函数类型的验证方法,这里不再赘述,留给读者自行验证。这里的结论是:过了一会儿,好像又回到了起点。“论证一:5种”其实没有错?毕竟,任何类型的底层都是基于5种类型中的一种实现的。然后继续。谈话很便宜,给我看代码。源代码文件列表如下图所示:以t_(type)开头的文件只有6个,除了“5个数据类型”外,还包括:t_stream.Stream是Redis5.0版本引入的一种新的数据类型。支持消费组,学习Kafka支持组播的持久化消息队列(支持组,不支持分区)。我们做如下验证:localhost:6379[2]>XADDstream:info*nameakuliasbumblebeeage35addresssz"1615012000623-0"localhost:6379[2]>typestream:infostream没问题:6种类型,我们重新整理一下:String(string)List(List)Set(集合)SortedSet(有序集合)Hash(散列)Streams(流信息)源码就是源码,让人豁然开朗。查谷歌众说纷纭,果然不对!那么问题的答案到这里就解决了吗?还没有。但现在不仅仅是开始,只是最后一步。源代码的内容不要肤浅,只看源代码文件列表,而不是源代码的内容。这是一个关于类型的枚举定义,0到6,什么?OBJ_MODULE?这到底是什么?请注意这个描述:*“module”对象类型是一种特殊的对象类型,表示该对象*是由Redis模块直接管理的。尤其是特字,属于特殊类型,其余6种都是非特殊类型。既然是特殊的,为什么它的枚举值5夹在stream的hash和non-special之间呢?由于历史原因,Redis4.0引入了模块扩展功能,这在当时被认为是最后一种。不过Redis5.0引入了Stream数据结构,可能是为了觊觎Kafka的市场份额。说白了就是和RocketMQ一样是在Kafka之后实现的。言归正传,那么枚举值的定义看起来是不是很熟悉我们日常的业务开发场景,因为状态值编号已经被占用,那么新添加的状态值只能排在后面,导致各种非-连续的。没错,脚踏实地。那么,该模块用在什么场景下呢?有很多场景。举个最常用的例子:LeakyBucket(漏桶算法),它是Redis4.0引入的redis-cell模块。示例如下:>cl.throttlemodule:leaky14306011)(integer)0#0表示允许1表示拒绝2)(integer)15#漏斗容量capacity3)(integer)14#漏斗剩余空间left_quota4)(integer)-1#如果拒绝了,需要多长时间重试,单位秒5)(integer)2#多久漏斗完全清空,单位秒,所以问题的答案就在这里解决?是的,最后通过分析源码得出了一个结论。结语Q:Redis有多少种数据类型?A:最新版本的Redis6.0只有7种类型。按照源码中枚举值定义的顺序,分别是:String(字符串)List(列表)Set(集合)SortedSet(有序集合)Hash(散列)Module(模块)Streams(流信息)Q:进阶函数类型,比如HyperLogLog、Bitmap等?A:高级函数类型是用API封装数据类型的应用。HyperLogLog、Bitmap、BloomFilter底层是String数据类型,Geospatial底层是SortedSet数据类型,cl.throttle(Redis-Cell)底层是Module数据类型。都可以通过typeKEY_NAME命令一一查看。所以下次面试官问你“面试Redis数据类型的3个连续问题”的时候,你可以回过头来让面试官看到你的理解,你对底层逻辑的把握比面试官自己更系统,更专业并给面试官带来一点惊喜。相信面试效果会完全不同。如果惊喜变成震惊怎么办?或许团队是一个固执保守的团队,面试官的考题可能只是出自套路题库,那你就可以慢慢合上简历,挥挥衣袖,带走一片浮云。最后,Talkischeap,Showmethecode.实践是检验真理的唯一标准,互相鼓励,请不要出错。作者:大黄蜂简介:曾供职于华为、腾讯等大型互联网公司,2018年5月加入独角兽公司akulaku担任技术管理岗位。在分期、理财等核心系统的架构设计方面具有丰富的实践经验。精通Redis和JVM,重视底层原理,对高级用法、协议、源码等有深入研究,并且有自己独特的团队管理理念,另辟蹊径,专注研究和发展质量与效益,为公司培养了众多年轻有潜力的年轻人,并多次获得各类奖项。编辑:陶佳龙征稿:如有意投稿或求报道,请加编辑微信gordonlonglong【原创稿件,合作网站转载请注明原作者及出处为.com】