• redis入门


    李子骅老师《Redis入门指南(第二版)》学习笔记

    简介

    Redis是一个开源的、高性能的、基于键值对的缓存与存储系统。

    redis和mysql的区别

    区别

    类型

    存储

    读写速度

    底层数据结构

    时间复杂度

    mysql

    关系型数据库

    磁盘

    较慢

    B+ tree

    O(logn)

    redis

    非关系型数据库

    内存

    较快

    键值对

    O(1)

    redis和Mencached的区别

    都是非关系型、基于内存的存储系统。

    redis支持字符串,散列,列表,集合,有序集,位图,超级日志和空间索引;而Memcached支持字符串和整数。

    redis是单线程模型,Memcached支持多线程,理论在多核服务器上Memcached的性能更高一些。

    Memcached不支持复制,redis支持主从复制。

    安装

    Installing Redis | Redis

    数据类型

    字符串 Strings

    Redis字符串是最基本的Redis数据类型,表示字节序列

    命令

    含义

    set key value

    赋值

    get key

    取值

    incr key

    递增(+1)

    incrby key value

    增加指定整数

    decrby key value

    减少指定整数

    incrbyfloat key value

    增加指定浮点数

    append key value

    向尾部增加值

    strlen key

    获取字符串长度

    mset key value [ key2 value2 ...]

    同时设置多个键值

    mget key value [ key2 value2 ...]

    同时获得多个键值

    列表 Lists

    Redis列表是按插入顺序排序的字符串列表。 内部是使用双向链表实现的,所以在列表两端添加元素的时间复杂度为O(1),获取越接近两端的元素速度就越快,代价是通过索引访问元素比较慢。

    命令

    含义

    lpush key value [ value ...]

    向列表左边增加元素

    rpush key value [ value ...]

    向列表右边增加元素

    lpop key

    从列表左边弹出元素

    rpop key

    从列表右边弹出元素

    llen key

    获取列表中元素个数

    lrange key start stop

    获得列表片段(包含两端)
    起始索引为0,右边第一个索引为-1

    lrem key count value
    count>0 从列表左边开始删除前count个值为value的元素
    count<0 从列表右边开始删除前|count|个值为value的元素
    count=0 删除所有值为value的元素

    删除列表中指定值

    lindex key index

    获得指定索引的元素值

    lset key index value

    设置指定索引的元素值

    ltrim key start stop

    删除指定范围外的所有元素

    linsert key before/after pivot value

    向列表中插入元素

    集合 Sets

    集合是唯一字符串的无序集合,其行为类似于您喜爱的编程语言(例如,Java HashSet、Python集合等)中的集合。 由于集合类型在redis内部是使用值为空的散列表实现的所以这些操作的时间复杂度都是O(1)

    集合与列表的区别

    集合

    列表

    存储内容

    至多223-1个字符串

    至多223-1个字符串

    有序性

    唯一性

    命令

    含义

    sadd key member [ member ...]

    增加元素

    srem key member [ member ...]

    删除元素

    smembers key

    获得集合中的所有元素

    sismember key value

    判断元素是否在集合中

    sdiff key [ key ...]

    集合差集运算

    sunion key [ key ...]

    集合并集运算

    sinter key [ key ...]

    集合交集运算

    scard key

    获得集合中元素个数

    srandmember key

    随机获得集合中元素

    spop key

    从集合中弹出一个元素

    散列 Hashes

    散列的键值也是一种字典结构,存储了字段和字段值的映射。 类似于Java的hashmap

    命令

    含义

    hset key field value

    赋值

    hget key field value

    取值

    hmset / hmget key field value [field1 value1 ...]

    赋值/取值多个字段

    hexists key field

    判断字段是否存在

    hsetnx key field value

    字段不存在时赋值

    hincrby key field num

    增加数字

    hdel key field [ field1 ...]

    删除字段

    hkeys key

    只获取字段名

    hvals key

    只获取字段值

    hlen key

    获得字段数量

    hgetall key

    获取字段和字段值

    有序集合 Sorted Sets

    有序集合是唯一字符串的集合,通过每个字符串的关联分数维持顺序

    命令

    含义

    zadd key score member [ score member ...]

    增加元素

    zscore key member

    获得元素分数

    zrange / zrevrange key start stop [withscores]

    获得排名在某个范围内的元素列表

    zrangebyscore key min max [withscores] [limit offset count]

    获得指定分数范围的元素

    zincrby key increment member

    增加某个元素的分数

    zcard key

    获得集合中元素的数量

    zcount key min max

    获得指定分数范围内的元素个数

    zrem key member [ member ...]

    删除一个或多个元素

    zremrangebyrank key start stop

    按照排名范围删除元素

    zremrangebyscore key min max

    按照分数范围删除元素

    zrank/zrevrank key member

    获得元素的排名

    Streams

    Redis流是一种数据结构,其作用类似于只追加日志。流有助于按照事件发生的顺序记录事件,然后将其联合起来进行处理

    Geospatial indexes

    Redis地理空间索引对于查找给定地理半径或边界框内的位置非常有用

    Bitmaps

    Redis位图允许您对字符串执行逐位操作。

    Bitfields

    Redis位字段有效地编码字符串值中的多个计数器。位字段提供原子获取、设置和增量操作,并支持不同的溢出策略

    HyperLogLog

    Redis HyperLogLog数据结构提供了大集合基数(即元素数量)的概率估计

    进阶

    事务

    redis中的事务(transaction),是一组命令的集合。

    使用multi开始一个事务,exec执行事务

    错误处理:

    1) 语法错误,命令不存在 / 命令参数个数不对 : 执行exec命令后,连正确的命令也不会执行

    2)运行错误,命令执行时出现的错误:事务里其他的命令都会执行,包括出错命令之后的命令

    过期时间

    设置过期时间: expire key 秒

    取消过期时间:persist key ; 使用set/getset为键赋值也会清除键的过期时间

    只对键值进行操作的命令(incr、lpush、hset、zrem)不会影响过期时间

    当服务器内存有限时,如果大量的使用缓存键且过期时间设置的过长就会导致redis占满内存;另一方面如果为了防止redis占用内存过大而将缓存键的过期时间设的太短,就可能导致缓存命中率过低并且大量内存白白的闲置,为此可以限制redis的最大使用内存

    设置方法:修改配置文件的maxmemory参数,限制redis最大可用内存大小(单位是字节),当超出了这个限制时redis会根据maxmemory-police参数指定的策略来删除不需要的键直到redis占用的内存小于指定内存

    排序

    sort

    排序列表

    排序集合

    排序有序集合: 会忽略元素的分数,只针对元素自身的值进行排序

    by

    by参数的语法为by参考键。其中参考键可以是字符串类型或者是散列类型键的某个字段(表示为 键名->字段名),如果提供了by参数,sort命令将不再依据元素自身的值进行排序,而是对每个元素使用元素的值,替换参考键中的第一个* 并获取其值,然后根据该值对元素进行排序

    散列类型的键:

    字符串类型的键:

    get

    get参数可以有多个,不影响排序,支持字符串类型和散列类型的键。 他的作用是使sort命令返回的结果不再是元素自身的值,而是get参数重指定的键值

    get # 返回元素本身的值

    store

    保存排序结果

    消息通知

    任务队列

    任务队列顾名思义就是“传递任务的队列”,与任务队列交互的实体有两类,一类是生产者,一类是消费者。生产者会将需要处理的任务放入任务队列中,而消费者不断的从任务队列中读入任务信息并执行

    好处:松耦合、易于扩展

    利用BRPOP命令,会一直阻塞链接,直到有新元素加入。

    格式: brpop 键名 超时时间 。 超市时间单位时秒,为0表示不限制等待时间

    如上图,实例A处于阻塞状态, 此时在实例B中像queue加入一个元素

    A马上返回了结果

    优先级队列

    格式:blpop queue:1 queue:2 queue:3 0

    解释:如果所有键都没有元素则阻塞;

    如果其中有一个键有元素则弹出;

    如果多个键有元素则按照从左往右的顺序取第一个键中的一个元素。

    发布/订阅模式

    发布/订阅模式同样可以实现进程间的消息传递

    发布者发消息: publish channel message , 返回值表示收到此条消息的订阅者数量,没有人订阅,则返回0

    订阅消息: subscribe channel [ channel ...]

    取消订阅消息: unsubscribe channel [ channel ...]

    实例A进入订阅状态:

    实例B发布消息:

    管道

    客户端和redis使用TCP协议链接,执行多个命令时每条都需要等待上一条命令执行完才能执行。

    redis对管道(pipelining)提供了支持,通过管道可以一次性发送多条命令,并在执行完后一次性将结果返回,当一组命令中每条命令都不依赖于之前命令的执行结果时可以将这组命令一起通过管道发出。

    持久化

    我们希望redis能将数据从内存中以某种形式同步到硬盘中,使得重启之后可以根据硬盘中的记录恢复数据,这一过程就是持久化。

    redis支持两种方式的持久化,一种是RDB方式,另一种是AOF方式

    ADB

    ADB的方式是通过快照完成的,当符合一定条件时Redis会自动将内存中的所有数据生成一份副本并存储在硬盘上。redis会在以下几种情况对数据进行快照

    1) 根据配置规则(redis.conf)进行自动快照

    2) 用户执行SAVE或BGSAVE命令

    执行save时,同步进行快照操作,执行过程会阻塞所有来自客户端的请求

    执行bgsave时,异步进行快照操作,使用lastsave获取最近一次快照的时间

    3) 执行FLUSHALL命令

    会清空所有数据

    4) 执行复制(replication)时

    设置了主从模式时,redis会在复制初始化时进行自动快照

    快照原理:

    1. redis使用fork函数复制一份当前进程(父进程)的副本(子进程)
    2. 父进程继续接收并处理客户端发来的命令,而子进程开始将内存中的数据写入硬盘中的临时文件
    3. 当子进程写入完所有数据后会用该临时文件替换旧的dump.rdb文件,至此一次快照操作完成

    优点:

    在进行快照的过程中不回修改rdb文件,只有快照结束后才会将旧的文件替换成新的,也就是说任何时候rdb文件都是完整的。rdb文件是经过压缩的二进制格式,占用空间小传输快

    缺点:

    一旦redis异常退出,就会丢失最后一次快照以后更改的所有数据

    AOF

    默认是关闭的,开启AOF持久化后每执行一条会更改redis中数据的命令,redis就会将该命令写入硬盘中的AOF文件,默认文件名是appendonly.aof

    缺点:

    在启动时redis会逐个执行AOF文件中的命令将硬盘中的数据载入到内存中,载入的速度相对rdb会慢一些

    集群

    复制

    为了避免单点故障,通常的做法是将数据库复制多个副本以部署在不同的服务器上,这样即使有一台服务器出现故障,其他服务器依然可以继续提供服务,为此redis提供了复制的功能。

    主数据库:可以进行读写操作,当写操作导致数据变化时自动将数据同步给从数据库

    从数据库:只读,接受主数据库同步过来的数据,一个从数据库只能有一个主数据库,从数据库自己也可作为主数据库

    启动一个主redis数据库 redis-server

    启动一个从redis数据库 redis-server --port 6380 --slaveof 127.0.0.1 6379

    redis实现复制的过程:

    1. 复制初始阶段。从数据库启动后,会向主数据库发送SYNC命令,主数据库收到后开始在后台保存快照(RBD持久化过程),并将快照期间收到的命令缓存起来。当快照完成后,redis会将快照文件和缓存命令发送给从数据库,从数据库收到后进行载入
    2. 复制同步阶段。主数据库执行任何会导致数据变化的命令都会异步的传送给从数据库

    通过复制可以实现读写分离,以提高服务器的负载能力。

    哨兵

    哨兵的作用

    1. 监控主数据库和从数据库是否正常运行
    2. 主数据库出现故障时自动将从数据库转换为主数据库

    哨兵是一个独立的进程,可以使用多个哨兵进行监控任务以保证系统足够稳健,哨兵不仅会同时监视主数据库和从数据库,哨兵之间也会相互监督。

    实现原理

    1)一个哨兵进程启动时会读取配置文件的内容,找到需要监控的主数据库,一个哨兵可同时监视多个redis主从系统

    sentinel monitor master-name ip redis-port quonum

    2)和主数据库建立连接后会定时执行下面的操作

    • 每十秒哨兵会向主数据库和从数据库发送info命令(实现新节点的自动发现)
    • 每两秒哨兵会向主数据库和从数据库的_sentinel_:hello频道发送自己的信息(与同样监控该数据库的哨兵分享自己的信息)
    • 每一秒哨兵会向主数据库和从数据库和其他哨兵节点发送ping命令(监控节点有无停止服务:主观下线-> 客观下线-> 选举领头哨兵进行故障恢复-> 挑选新的主节点)
  • 相关阅读:
    高性能可编程射频移相器介绍
    Android10.0 锁屏分析-KeyguardPatternView图案锁分析
    优惠来袭,工业树莓派特惠季火爆进行中
    linux 增加交换区
    【解决方案】成功解决将XGBoost中plot_importance绘图时出现的f0、f1、f2、f3、f4、f5等改为对应特征的字段名
    设计模式15——享元模式
    中断上下文和进程上下文
    分布式内存计算Spark环境部署与分布式内存计算Flink环境部署
    ASEMI整流桥UD6KB100,UD6KB100尺寸,UD6KB100特征
    口袋参谋:淘宝生意参谋指数,如何一键转换成真实数值?
  • 原文地址:https://blog.csdn.net/Lvxueqinga/article/details/128180138