专栏首页喔家ArchiSelf全栈必备 Redis基础

全栈必备 Redis基础

在《老码农眼中的简明AI》一文中提到了图灵机和冯诺伊曼的计算机体系结构,数据存储是整个计算机软件系统中的一个关键节点。从个人电脑上的软件到基于计算机网络的分布式系统,存储系统更是基础环节,而且还承担着整个系统的数据责任。

应用程序离不开数据存储,关系型数据库的诞生为软件系统的发展揭开了一个新的时代,而互联网应用中大量的非结构化数据为非关系型数据库——NoSQL,提供了广泛的应用场景。

NoSQL 技术与高伸缩性无缝融合,很多技术同时具备了高分布性和高性能, 也是大数据分析的存储基石。大多数时间里,它们使 现有RDBMS 技术所实现的架构更加完整,例如 作为缓存服务器,搜索引擎,非结构化存储,易变信息存储等。大约可以分为4类:

  • Key/value型NoSQL
  • 列存储型NoSQL
  • 面向文档的存储型NoSQL
  • 图存储型NoSQL

关于这些NoSQL 的应用场景可以参见《NoSQL 之于大数据》。

面对这些NoSQL, 如果只需掌握一种NoSQL,那可能就是key/value型的Redis了。

什么是Redis

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。

它支持多种类型的数据结构,如字符串, 散列, 列表, 集合, 有序集合与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。

Redis 内置了复制,LUA脚本, LRU驱动事件,事务和不同级别的磁盘持久化, 并通过 Redis哨兵(Sentinel)和自动分区(Cluster)提供高可用性。

以上来自redis.cn 上的介绍,简单的说,Redis是一个支持多种数据结构并且能够持久化的高性能NoSQL 数据库。

Redis 的存储实现

Redis作为一个性能高达10万qps的key/value存储类型的NoSQL数据库,大致的存储实现体系如下:

一个RedisServer包含了N个redisDb,redisDb有dict的指针和失效时间的指针,核心是dictEntry 指针链表的指针,每一个具体的dictEntry链表节点存储了任意类型的key 和 value,不论是key还是value 都可以是redisObject。可以认为,指针链表的特性对redis的性能做出重要的作用。

Redis 中的数据结构与存储实现关系如下:

INT压缩存储String,常量数字对象是共享的。SDS 存储string,变长的字符数组以及共享的常用字符串等。双端列表LINKEDLIST来存储list,支持双向遍历。HT是hash表,存储set和hash,根据填充率缩放,支持事件触发。INTSET压缩存储set,编码为int16_t/ int32_t/ int64_t。SKIPLIST存储有序集,联合dict处理zset。ZIPLIST通过双端指针压缩存储hash、list和zset。

Redis存储实现中的网络模型支持Epoll/Select/Kqueue等,事件模型主要是TimeEvent/FileEvent。由于FileEvent处理器是单线程的,所以 redis 是单线程的模型。Redis 单线程模型是纯内存操作,核心是基于非阻塞的 IO 多路复用机制,单线程反而避免了多线程的频繁上下文切换问题,因而整体的存储实现性能很高。

Redis 的常见命令集

Redis 简洁易用,为了方便记忆,命令集分类如下:

访问Redis的客户端类型丰富,几乎涵盖了大多数的主流编程语言:

Redis 的集群部署

Redis 自2.4 版本开始就可以在生产环境上稳定可用了,在2.6版本引入了Lua脚本和Watch dog,2.8版本对主从同步进行了优化,并开始支持Sentinel 和 HyperLog。Redis 2.x 的集群主要是通过主从同步实现的,数据是异步复制和增量同步。

有限状态机在主从同步和数据持久化方面起到了重要的作用。数据持久化是通过快照实现的,通信协议是RESP,一种便于实现和理解的二进制安全协议。AOF 最终通过fsync写入磁盘实现数据的持久化。

从3.0开始,Redis 支持cluster,cluster内部的各节点间采用的Gossip分布式协议。通过多数原则判断节点是否宕机,由gossip协议传播判活信息,选举出新的替代者,由gossip协议传播选举结果。

Redis 集群可以实现自动故障切换,副本迁移和在线的重新分片。分片变化,数据迁移同样通过gossip协议达成一致。

然而,Redis cluster 同样存在着不足,例如随着节点的增加,故障切换会有大幅的增加,gossip传播信息需要一段时间,整机房切换比较慢。按key同步阻塞的迁移对读写影响较大,Gossip协议的调试非常困难,给故障的排除会带来诸多的不便。

关注redis 的官方网站,可以看到redis 4.0 以来的诸多新变化。

Redis 的常见应用

Redis 的应用十分广泛,在key/value 的NoSQL中有着突出的性能体现,甚至和文档型NoSQL——MongoDB 在某些方面有着类似的作用。Redis, Memcache和MongoDB 的对比如下图所示:

根据用户标识获取用户的相关数据在互联网应用中是一种常见的场景,这类数据具有读写量大,但单条数据不长,并且对某些字段经常进行更新等特点,一般都会使用redis 这样类型key/value 数据库来实现。Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得在执行这些操作时非常简单,Redis正好提供了这两种数据结构,因而对排行榜类的场景

对于分布式锁的业务,Redis 可以提供高性能的分布式锁服务,例如电商业务的秒杀场景,全局自增ID等等。

对于系统架构而言, Redis 有时候甚至成为了缓存的代名词,关于Redis 在分布式缓存方面的各种应用,可以参考《深入分布式缓存——从原理到应用》一书中的诸多章节。

深入Redis,还可以发现很多有趣的用法,例如将redis 作为消息队列等等,一文难以描述Redis,但可以作为全栈需要掌握的一个基础。

【参考阅读】

本文分享自微信公众号 - 喔家ArchiSelf(wireless_com),作者:半吊子全栈工匠

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • coding之外的3个日常:开会、提问和读书

    对工程师思维习惯和工作方式的建议有很多,但在思维和行动之间往往存在着鸿沟,以至于很多方式被某些人视为原则,而被另一些人视为有用的废话。

    半吊子全栈工匠
  • 数据存储的趣事

    随着更新、更好、更快的存储介质的到来,一个字节的数据能够以多种不同的方式进行存储。字节是数字信息的单位,通常指八位,比特位是一个信息单位,可以表示为0或1,表示...

    半吊子全栈工匠
  • 一文弄清物联网的OTA

    许多嵌入式系统部署在人类操作员很难或无法访问的地方。 对于物联网应用程序来说尤其如此,物联网应用程序通常数量较大,电池寿命有限。 一些例子是监视人或机器健康状况...

    半吊子全栈工匠
  • Redis 和 Memcached 的区别详解

    Redis的作者Salvatore Sanfilippo曾经对这两种基于内存的数据存储系统进行过比较:

    哲洛不闹
  • 《吐血整理》Redis 性能优化的 13 条军规!

    从以上数据可以看出,在 key 不变的情况下,value 值越大操作效率越慢,因为 Redis 对于同一种数据类型会使用不同的内部编码进行存储,比如字符串的内部...

    Java中文社群-磊哥
  • 《吐血整理》Redis 性能优化的 13 条军规!史上最全

    从以上数据可以看出,在 key 不变的情况下,value 值越大操作效率越慢,因为 Redis 对于同一种数据类型会使用不同的内部编码进行存储,比如字符串的内部...

    Java中文社群-磊哥
  • Redis与Memcached的区别

    本文我们将探讨 Redis (远程字典服务器). Redis是一个开源的、内存型的键值存储。它也被看作为一个字典型的数据结构服务器,因为它的键值不仅仅是字符串,...

    用户1263954
  • 如何在 Ubuntu 20.04 上安装和配置 Redis

    本文最先发布在:https://www.itcoder.tech/posts/how-to-install-and-configure-redis-on-ubu...

    雪梦科技
  • Redis(一)基础

    性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s。

    码农小胖哥
  • 非常值得一看的35个Redis面试题总结(二)

    在Redis当中,有生存期的key被称为volatile。在创建缓存时,要为给定的key设置生存期,当key过期的时候(生存期为0),它可能会被删除。

    互扯程序

扫码关注云+社区

领取腾讯云代金券