Redis数据读取与存储

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

本文主要记录Redis的数据读取和存储,以下均基于Redis 3.2以上的版本。


一、Redis是什么?

Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。其支持五大数据存储类型,提供高性能的数据读取,常用作于缓存架构。并且支持集群化部署,满足服务高可用的需求。

二、Redis数据读取

为保证读取高性能,Redis的数据均储存于内存中,且Redis采用单线程读写方式,也使得Redis不会出现线程不安全的问题。Redis的数据存储格式采用Key-Value设计,在读取的时候,根据Key获取来获取Value操作也相应的变得简单和快捷。

三、Redis数据存储

Redis通过dic维护了多个Key-value的映射关系来实现数据的存储,这个映射关系的Key是String类型,而Value可以是多种数据类型。Redis提供了五种Value类型,分别为String、List、Hash、Set、Sorted Set。为了满足这五种数据类型的存储,Redis又采用了多种数据结构来保证数据存储。以下通过分析每种数据类型所采用的数据结构来分析Redis数据的存储。

1.String

String是Redis中简单的一种数据类型,其通常用于简单数据缓存、计数等,其底层实现为sds(一种可动态分配内存的字符串)和long。

一般情况下String的底层采用的是sds,由于Redis的数据主要存储在内存空间,所以其设计会尽可能的节约内存空间,所以如果当存储的类型为数值型的话,Redis则会转换成long型存储,这样可大大的节省内存空间,并且更加方便的实现计数等功能。

如果先set了一个数值类型的值,再在同一个Key 设置一个字符串的话,Redis底层就会直接转换成sds来存储了。

2.List

List 的实现为一个双向链表,一般用作队列使用存储列表类型的值,其支持在队列两端进行push和pop操作,以及其任意位置的存取操作。可用于好友列表、推送列表的实现。

List的底层实现方式为quicklist。quicklist是一个双向链表,包含有多个节点,其每个节点均是一个ziplist,ziplist的内存是一整块连续内存,储存效率高,内存随便少,但修改的效率很低。双向链接的修改效率高,但其内存开销大, 内存碎片多。于是quicklist将二者的优点结合起来实现。具体的可参考:http://zhangtielei.com/posts/blog-redis-quicklist.html

3.Hash

Hash可用与存储对象以及对象的字段值,对象的一个字段对应一个hash结构,能够很方便的操作一个对象。

Hash的底层实现有两种,分别为ziplist和dic(字典)。当数据量比较少时,底层采用ziplist的方式进行存储结构。当数据超过配置的条件之一时,底层将会转化为dic进行存储。配置如下:

  • hash-max-ziplist-entries 512:Hash中的filed-value项大于512时,底层转换为dic
  • hash-max-ziplist-value 64:当value值长度超过64时,底层转换为dic。

之所以会这样设计,是因为当ziplist数据量过大时,ziplist有以下两个缺点,

  • 由于ziplist是一整块连续内存,当数据量大时,可能会频繁的realloc触发内存的拷贝,内存拷贝会占用更大的空间,大大的降低了性能
  • 当ziplist的数据项过多时,其查询效率就会变得很低,因为ziplist查询是遍历查询的。

4.Set

Set是一个不允许有重复值得无序集合,其区别于List的有以下几点功能:

  • Set可提供全局去重操作
  • Redis可基于Set实现集合的交集、并集和差集,可实现共同好友等之内的集合之间操作的功能

Set的底层实现为intset(有序整数集合)和dic,当满足以下条件时,Redis采用intset结构来实现Set,否则就是用dic来实现Set

  • 存储是整数类型的数据时,采用intset
  • 存储的数据条数小于512个时,采用intset

Set集合会采用intset结构来存储,主要是因为intset 和 ziplist类似,内存空间碎片少,并且查找效率高。具体可参考:http://zhangtielei.com/posts/blog-redis-intset.html

5.Sorted Set

Sorted Set是一个有序集合,其区分于Set的功能是其提供了一个权重参数score,集合中的元素按照score来进行排序。可用来实现排行榜的功能

Sorted Set的底层实现为ziplist和zset(dic+skiplist),当满足以下条件时,则使用ziplist,否则使用zset

  • 集合项的个数小于128个
  • 集合中每个数据的小于64字节

当数据量大时,ziplist的查询效率会变低。但dic的查询效率也不高,为了保证高效的性能,Redis采用dic+skiplist结构来实现Sorted Set,skiplist提供高效的查询。具体可参考:http://zhangtielei.com/posts/blog-redis-skiplist.html


总结

以上解释了Redis五大基本数据类型的使用和存储原理,可以看出Redis在数据存储和查询的设计上均偏向于内存的优化和查询的高效,这也是Redis为什么能够以单线程模式支持超10w/s的查询效率的原因。

  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值