• Redis基础:特点(内存运行、原子性、持久化)、5种基本数据类型与3种特殊数据类型、redis命令、发布订阅机制、事务(单条命令原子性事务不是原子性)、数据备份与恢复、安全


    一、redis 简介

      Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。

    1、Redis 与其他 key - value 缓存产品有以下三个特点:

    (1)Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。

    (2)Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。

    (3)Redis支持数据的备份,即master-slave模式的数据备份。

    2、Redis 优势

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

    (2)丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。

    (3)原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。

    (4)丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

    3、Redis与其他key-value存储有什么不同?

    (1)Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。

    (2)Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。

      在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。

      同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。

    二、数据类型

    1、Redis支持:

    (1)五种基本数据类型:string(字符串),hash(哈希),list(列表),set(集合)及 zset(sorted set:有序集合);

    (2)三种特殊数据类型:HyperLogLog(用来做基数统计的算法)、GEO(用于存储地理位置信息)、Stream(用于消息队列)

    2、string 类型是 Redis 最基本的数据类型,最大能存储 512MB。

      string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据,比如jpg图片或者序列化的对象。

    3、hash 是一个键值(key=>value)对集合。Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。

      每个 hash 可以存储 232 -1 键值对(40多亿)

    4、List(列表)是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)。

    5、Set(集合)是 string 类型的无序集合。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。最大的成员数为 232 - 1。

    6、zset(sorted set:有序集合)和 set 一样,不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。

    三、redis 命令

    1、Redis 命令用于在 redis 服务上执行操作。要在 redis 服务上执行命令需要一个 redis 客户端。

      Redis 客户端的基本语法为:redis-cli

      在远程 redis 服务上执行命令,同样我们使用的也是 redis-cli 命令:redis-cli -h host -p port -a password

      注意:有时候会有中文乱码。要在 redis-cli 后面加上 --raw:redis-cli --raw,就不会有中文乱码了。

    2、关于各种数据类型的命令,详见:https://www.runoob.com/redis/redis-commands.html

    四、发布订阅

    1、Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。Redis 客户端可以订阅任意数量的频道。

      下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:

      当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:

    2、实例介绍

    -- 创建了订阅频道名为 runoobChat
    redis 127.0.0.1:6379> SUBSCRIBE runoobChat
    Reading messages... (press Ctrl-C to quit)
    1) "subscribe"
    2) "redisChat"
    3) (integer) 1
    
    -- 重新开启个 redis 客户端,然后在同一个频道 runoobChat 发布两次消息,订阅者就能接收到消息。
    redis 127.0.0.1:6379> PUBLISH runoobChat "Redis PUBLISH test"
    (integer) 1
    redis 127.0.0.1:6379> PUBLISH runoobChat "Learn redis by runoob.com"
    (integer) 1
    
    -- 订阅者的客户端会显示如下消息
     1) "message"
    2) "runoobChat"
    3) "Redis PUBLISH test"
     1) "message"
    2) "runoobChat"
    3) "Learn redis by runoob.com"

    五、redis 事务

    1、Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:

    (1)批量操作在发送 EXEC 命令前被放入队列缓存。

    (2)收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。

    (3)在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

    2、一个事务从开始到执行会经历以下三个阶段:开始事务、命令入队、执行事务。

    3、实例:以下是一个事务的例子, 它先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令:

    redis 127.0.0.1:6379> MULTI
    OK
    
    redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
    QUEUED
    
    redis 127.0.0.1:6379> GET book-name
    QUEUED
    
    redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
    QUEUED
    
    redis 127.0.0.1:6379> SMEMBERS tag
    QUEUED
    
    redis 127.0.0.1:6379> EXEC
    1) OK
    2) "Mastering C++ in 21 days"
    3) (integer) 3
    4) 1) "Mastering Series"
       2) "C++"
       3) "Programming"

      单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的

      事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做

    六、HyperLogLog

      Redis 在 2.8.9 版本添加了 HyperLogLog 结构。Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。

      在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

    七、GEO

      Redis GEO 主要用于存储地理位置信息,并对存储的信息进行操作,该功能在 Redis 3.2 版本新增。

    八、Redis Stream

      Redis Stream 是 Redis 5.0 版本新增加的数据结构。Redis Stream 主要用于消息队列(MQ,Message Queue),Redis 本身是有一个 Redis 发布订阅 (pub/sub) 来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。简单来说发布订阅 (pub/sub) 可以分发消息,但无法记录历史消息。

      而 Redis Stream 提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失

      Redis Stream 的结构如下所示,它有一个消息链表,将所有加入的消息都串起来,每个消息都有一个唯一的 ID 和对应的内容:

      每个 Stream 都有唯一的名称,它就是 Redis 的 key,在我们首次使用 xadd 指令追加消息时自动创建。上图解析:

    1、Consumer Group :消费组,使用 XGROUP CREATE 命令创建,一个消费组有多个消费者(Consumer)。

    2、last_delivered_id :游标,每个消费组会有个游标 last_delivered_id,任意一个消费者读取了消息都会使游标 last_delivered_id 往前移动。

    3、pending_ids :消费者(Consumer)的状态变量,作用是维护消费者的未确认的 id。 pending_ids 记录了当前已经被客户端读取的消息,但是还没有 ack (Acknowledge character:确认字符)。

    九、数据备份与恢复

    1、备份数据:Redis SAVE 命令用于创建当前数据库的备份。该命令将在 redis 安装目录中创建dump.rdb文件。

      创建 redis 备份文件也可以使用命令 BGSAVE,该命令在后台执行。

    2、恢复数据:如果需要恢复数据,只需将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可。获取 redis 目录可以使用 CONFIG 命令,如下所示

    redis 127.0.0.1:6379> CONFIG GET dir
    1) "dir"
    2) "/usr/local/redis/bin"
    -- 以上命令 CONFIG GET dir 输出的 redis 安装目录为 /usr/local/redis/bin

    十、redis 安全

      我们可以通过 redis 的配置文件设置密码参数,这样客户端连接到 redis 服务就需要密码验证,这样可以让你的 redis 服务更安全。

    -- 通过以下命令查看是否设置了密码验证:
    127.0.0.1:6379> CONFIG get requirepass
    1) "requirepass"
    2) ""
    
    -- 默认情况下 requirepass 参数是空的,这就意味着你无需通过密码验证就可以连接到 redis 服务。
    
    -- 你可以通过以下命令来修改该参数:
    127.0.0.1:6379> CONFIG set requirepass "runoob"
    OK
    127.0.0.1:6379> CONFIG get requirepass
    1) "requirepass"
    2) "runoob"
    
    -- 设置密码后,客户端连接 redis 服务就需要密码验证,否则无法执行命令。 

      使用密码连接:AUTH 命令基本语法格式如下

    127.0.0.1:6379> AUTH password

    十一、管道技术

    1、Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。

    2、管道技术最显著的优势是提高了 redis 服务的性能。

    十二、分区

    1、Redis 有两种类型分区。 假设有4个Redis实例 R0,R1,R2,R3,和类似user:1,user:2这样的表示用户的多个key,对既定的key有多种不同方式来选择这个key存放在哪个实例中。也就是说,有不同的系统来映射某个key到某个Redis服务。

    2、范围分区:最简单的分区方式是按范围分区,就是映射一定范围的对象到特定的Redis实例。

      比如,ID从0到10000的用户会保存到实例R0,ID从10001到 20000的用户会保存到R1,以此类推。这种方式是可行的,并且在实际中使用,不足就是要有一个区间范围到实例的映射表。这个表要被管理,同时还需要各种对象的映射表,通常对Redis来说并非是好的方法。

    3、哈希分区:另外一种分区方法是hash分区。这对任何key都适用,也无需是object_name:这种形式,像下面描述的一样简单:

    (1)用一个hash函数将 key 转换为一个数字,比如使用 crc32 hash 函数。对 key foobar 执行 crc32(foobar) 会输出类似93024922的整数

    (2)对这个整数取模,将其转化为0-3之间的数字,就可以将这个整数映射到4个Redis实例中的一个了。93024922 % 4 = 2,就是说key foobar应该被存到R2实例中

      注意:取模操作是取除的余数,通常在多种编程语言中用 % 操作符实现。

  • 相关阅读:
    【BZOJ 1579】 1579: [Usaco2009 Feb]Revamping Trails 道路升级 (最短路)
    有限广播地址与直接广播地址
    人生苦短之我用Python篇(线程/进程、threading模块:全局解释器锁gil/信号量/Event、)
    SQL基础二
    Ubuntu命令:sudo、shutdown、apt-get、vim
    SQL基础一
    MPLS基础一
    第一章 Linux系统入门
    P4简介:数据平面的编程语言
    人生苦短之我用Python篇(安装第三方库、正则表达式)
  • 原文地址:https://www.cnblogs.com/goloving/p/15234205.html
Copyright © 2020-2023  润新知