一 Redis初步介绍

1 redis介绍

Redis是一种基于键值对(key-value)的NoSQL数据库,与很多键值对数据库不同的是

  • Redis中的值可以是由string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、HyperLogLog、GEO(地理信息定位)等多种数据结构和算法组成,因此Redis可以满足很多的应用场景

  • Redis会将所有数据都存放在内存中,所以它的读写性能非常惊人

  • Redis还可以将内存的数据利用快照和日志的形式保存到硬盘上,这样在发生类似断电或者机器故障的时候,内存中的数据不会“丢失”

  • 除了上述功能以外,Redis还提供了键过期、发布订阅、事务、流水线、Lua脚本等附加功能。

1.1 为什么高性能?

正常情况下,Redis执行命令的速度非常快,官方给出的数字是读写性能可以达到10万/秒,当然这也取决于机器的性能。

  • 纯内存操作:数据存放在内存中,内存的响应时间大约是 100纳秒 ,这是Redis每秒万亿级别访问的重要基础。

  • IO多路复用模型:避免在网络IO上浪费过多时间,select方法可能同时监控n个socket是否达到可读状态,无需顺序排队处理。

  • 单线程:避免了线程切换和竞态产生的消耗

1.2 能保证数据持久性?

通常看,将数据放在内存中是不安全的,一旦发生断电或者机器故障,重要的数据可能就会丢失,因此Redis提供了两种持久化方式:RDB和AOF,即可以用两种策略将内存的数据保存到硬盘中,这样就保证了数据的可持久性。

1.3 使用场景有哪些?

  • 缓存:缓存机制几乎在所有的大型网站都有使用,合理地使用缓存不仅可以加快数据的访问速度,而且能够有效地降低后端数据源的压力。

  • 排行榜系统:排行榜系统几乎存在于所有的网站,Redis提供了列表和有序集合数据结构,合理地使用这些数据结构可以很方便地构建各种排行榜系统。

  • 计数器应用:计数器在网站中的作用至关重要,如果并发量很大对于传统关系型数据的性能是一种挑战。Redis天然支持计数功能而且计数的性能也非常好,可以说是计数器系统的重要选择。

  • 标签系统:电商进行商品推送会考虑到每个用户的标签信息,推送用户感兴趣的商品。

1.4 对比memcached

  • redis数据类型丰富:Redis支持的数据类型要丰富得多,不仅支持简单的k/v类型的数据,同时还提供String、List、Set、Hash、Sorted Set等数据结构的存储。memcache支持简单数据类型,需要客户端自己处理复杂对象

  • redis支持数据持久性:redis支持数据落地持久化存储,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。 memcache不支持数据持久存储 

  • redis集群管理:Memcached本身并不支持分布式,因此只能在客户端只能自己实现,比如通过哈希这样的分布式算法来实现分布式存储。而Redis在服务器端实现了分布式存储。

  • memcached是多线程,非阻塞io网络模型;redis是单线程io多路复用模型。两者间速度差不多;

2 数据结构

ridis对外提供的数据结构包括:string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)等。

但实际上每种数据结构都有多种底层内部编码实现,这样Redis会在合适的场景选择合适的内部编码。

2.1 字符串

【基本操作】

字符串类型是Redis最基础的数据结构。

  • incrby(自增指定数字)

  • decrby(自减指定数字)

  • incrbyfloat(自增浮点数)

  • append key value(追加值)

【数据结构】

·int:8个字节的长整型。

·embstr:小于等于39个字节的字符串。

·raw:大于39个字节的字符串。

Redis会根据当前值的类型和长度决定使用哪种内部编码实现。

【使用场景举例】

计数:许多应用都会使用Redis作为计数的基础工具,它可以实现快速计数、查询缓存的功能,同时数据可以异步落地到其他数据源。

开发提示:实际上一个真实的计数系统要考虑的问题会很多:防作弊、按照不同维度计数,数据持久化到底层数据源等。

long incrVideoCounter(long id) {
    key = "video:playCount:" + id;
    return redis.incr(key);
}

2.2 哈希

【基本操作】

几乎所有的编程语言都提供了哈希(hash)类型,它们的叫法可能是哈希、字典、关联数组。在Redis中,哈希类型是指键值本身又是一个键值对结构,形如value={{field1,value1},...{fieldN,valueN}}

【数据结构】

哈希类型的内部编码有两种:

  • ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries 配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64 字节)时,Redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的 结构实现多个元素的连续存储,所以在节省内存方面比hashtable更加优秀。

  • hashtable(哈希表):当哈希类型无法满足ziplist的条件时,Redis会使 用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而 hashtable的读写时间复杂度为O(1)。

【选型举例】

如果缓存用户信息,下面给出三种方案的实现方法和优缺点分析。

  • 原生字符串类型:每个属性一个键(不建议使用)。

    • 优点:简单直观,每个属性都支持更新操作。

    • 缺点:占用过多的键,内存占用量较大,同时用户信息内聚性比较差。

  • 序列化字符串类型:将用户信息序列化后用一个键保存。

    • 优点:简化编程,如果合理的使用序列化可以提高内存的使用效率(时间复杂度相比hash较低)。

    • 缺点:序列化和反序列化有一定的开销,同时每次更新属性都需要把全 部数据取出进行反序列化,更新后再序列化到Redis中。

  • 哈希类型:每个用户属性使用一对field-value,但是只用一个键保存。

  • 优点:简单直观,如果使用合理可以减少内存空间的使用。

  • 缺点:要控制哈希在ziplist和hashtable两种内部编码的转换,hashtable会消耗更多内存。

我们用string是否合理?

2.3 列表

【基本操作】

列表(list)类型是用来存储多个有序的字符串,一个列表最多可以存储2 32 -1个元素。列表是一种比 较灵活的数据结构,它可以充当栈和队列的角色,在实际开发上有很多应用场景。

列表类型有两个特点:

  • 列表中的元素是有序的,可以通过索引下标获取某个元素或者某个范围内的元素列表。

  • 列表中的元素可以是重复。

【数据结构】

列表类型的内部编码有两种。

  • ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置 (默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时 (默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使 用。

  • linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用 linkedlist作为列表的内部实现。

【使用场景举例】

  • 消息队列 :Redis的lpush+brpop命令组合即可实现阻塞队列,生产 者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令 阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用 性。

2.4 集合

【基本操作】

集合(set)和列表类型不一 样的是,集合中不允许有重复元素,并且集合中的元素是无序的,一个集合最多可以存储2 32 -1个元 素。Redis除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集,合理地使用好集合类型,能在实际开发中解决很多实际问题。

【数据结构】

集合类型的内部编码有两种:

  • intset(整数集合):当集合中的元素都是整数且元素个数小于set-maxintset-entries配置(默认512个)时,Redis会选用intset来作为集合的内部实 现,从而减少内存的使用。

  • hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使 用hashtable作为集合的内部实现。

【使用场景举例】

标签系统(tag):通过sadd、srem、sismenber等操作可实现用户标签系统。例如一个电子商务的网站会对不同标签的用户做不同类型的推荐,比如对数码产品 比较感兴趣的人,在各个页面或者通过邮件的形式给他们推荐最新的数码产品,通常会为网站带来更多的利益。

2.5 有序集合

【基本操作】

它保留了集合不能有重复成员的特性, 且有序集合中的元素可以排序。它和列表使用索引下标作为排序依据不同,它给每个元素设置一个分数(score)作为排序的依据。有序集合提供了获取指定分数和元素范围查询、计算成员排名等功能,合理的利用有序集合,能帮助 我们在实际开发中解决很多问题。

 

【数据结构】

有序集合类型的内部编码有两种:

  • ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplistentries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配 置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist 可以有效减少内存的使用。

  • skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作 为内部实现,因为此时ziplist的读写效率会下降。

【使用场景举例】

排行榜系统:例如视频网站需要对用 户上传的视频做排行榜,榜单的维度可能是多个方面的:按照时间、按照播放数量、按照获得的赞数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值