Redis知识笔记及命令全

文章目录

  • NoSQL
    • 特性
    • 大数据的3V和3高
    • 四大分类
    • 分布式数据库中的CAP原理CAP+BASE
  • Redis
    • 特点
    • 应用场景
  • Redis详解
    • Redis数据类型
    • Redis命令
      • key关键字
      • String字符串
      • List列表
      • Set集合
      • Hash哈希
      • Zset有序集合
    • Redis配置
    • Redis持久化
        • RDB
          • 应用场景
          • 触发机制
          • 总结
        • AOF
          • 配置之Appendfsync
          • 重写机制(Rewrite)
          • 总结
        • 对比使用
    • Redis的事务
      • 事务命令
        • 正常执行
        • 放弃事务
        • 全体连坐
        • 部分支持事务
        • watch监控
    • Redis的发布和订阅
      • 实例
      • Redis 发布订阅命令
    • Redis复制
      • 一主二从
      • 薪火相传
      • 反客为主
      • 复制原理
      • 哨兵模式(sentinel)

NoSQL

泛指菲关系型数据库。大规模数据存储,这些类型的数据存储不需要固定的模式,无需多余的操作就可以横向扩展

特性

  • 易扩展

    去掉关系数据库的关系型特性,数据之间无关系,这样就非常容易扩展。

  • 大数据量高性能

    非常高的读写性能,关系型数据库使用Query Cache,每次表更新Cache就失效,Cache性能不高。NoSQL的Cache是记录级的,性能高

  • 多样灵活的数据模型

  • 传统RDBMS和NoSQL

    RDBMS

    • 高度组织化结构化数据
    • 结构化查询语言(SQL)
    • 数据和关系都存储在单独的表中。
    • 数据操纵语言,数据定义语言
    • 严格的一致性
    • 基础事务

    NoSQL

    • 代表着不仅仅是SQL
    • 没有声明性查询语言
    • 没有预定义的模式
      -键 - 值对存储,列存储,文档存储,图形数据库
    • 最终一致性,而非ACID属性
    • 非结构化和不可预知的数据
    • CAP定理
    • 高性能,高可用性和可伸缩性

大数据的3V和3高

  • 海量

  • 多样

  • 实时

  • 高并发

  • 高可扩

  • 高性能

四大分类

  • KV键值

    • redis
    • memcache 多线程,非阻塞IO复用的网络模型
    • tail
    • BerkeleyDB
  • 文档型数据库

    • MongoDB

      • MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。

        MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

    • CouchDB

  • 列存储数据库

    • HBase
    • Cassandra
    • 分布式文件系统
  • 图关系数据库

    • Neo4J
    • InfoGrid

分布式数据库中的CAP原理CAP+BASE

  • C:Consistency(强一致性)
  • A:Availability(可用性)
  • P:Partition tolerance(分区容错性)

CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。
而由于当前的网络硬件肯定会出现延迟丢包等问题,所以

分区容忍性是我们必须需要实现的。

所以我们只能在一致性和可用性之间进行权衡,没有NoSQL系统能同时保证这三点。

C:强一致性 A:高可用性 P:分布式容忍性(分区容错性)

  • CA 传统Oracle数据库

  • AP 大多数网站架构的选择

  • CP Redis、Mongodb

注意:分布式架构的时候必须做出取舍。
一致性和可用性之间取一个平衡。多余大多数web应用,其实并不需要强一致性。
因此牺牲C换取P,这是目前分布式数据库产品的方向

一致性与可用性的决择

对于web2.0网站来说,关系数据库的很多主要特性却往往无用武之地

数据库事务一致性需求
  很多web实时系统并不要求严格的数据库事务,对读一致性的要求很低, 有些场合对写一致性要求并不高。允许实现最终一致性。

数据库的写实时性和读实时性需求
  对关系数据库来说,插入一条数据之后立刻查询,是肯定可以读出来这条数据的,但是对于很多web应用来说,并不要求这么高的实时性,比方说发一条消息之 后,过几秒乃至十几秒之后,我的订阅者才看到这条动态是完全可以接受的。

对复杂的SQL查询,特别是多表关联查询的需求
  任何大数据量的web系统,都非常忌讳多个大表的关联查询,以及复杂的数据分析类型的报表查询,特别是SNS类型的网站,从需求以及产品设计角 度,就避免了这种情况的产生。往往更多的只是单表的主键查询,以及单表的简单条件分页查询,SQL的功能被极大的弱化了。

Redis

Remote Dictionary Server远程字典服务器。C语言编写

是一个高性能的KV键值型分布式内存数据库,基于内存运行,并支持持久化的NoSQL数据库。(数据结构数据库)

使用Redis因为它读取数据快,直接从内存中读取,支持持久化,支持丰富的数据类型,支持事务,且拥有丰富的特性,可用于缓存,消息,设置key过期时间等等

特点

  • Redis使用单线程的IO复用模型
  • 支持数据的持久化,先将数据存在内存当中,可已将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用
  • 不仅支持简单的KV类型的数据,还提供了String,Hash,Set,ZSet,List
  • 支持数据的备份,即master-slave模式的数据备份

应用场景

  • 内存存储和持久化:redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务(缓存:提高网站访问速度,降低数据库压力)
  • 取最新N个数据的操作:如将最新的10条评论的ID放到Redis的List集合中
  • 模拟类似于HttpSession这种需要设定过期时间的功能
  • 发布、订阅消息系统
  • 定时器,计数器,排行榜

Redis详解

  • 单进程模型来处理客户端的请求。对读写等时间的响应是通过对epoll函数的包装来做到的。

  • 默认16个数据库,类似数组下表从0开始,初始默认使用0号库

  • select命令切换数据库(0-15)

    • redis-server /opt/redis-3.0.4/redis.config服务端启动
    • redis-cli -p 3679客户端连接
  • Dbsize查看当前数据库的key的数量

    • keys *查看所有key
    • keys k1(keys k?)
  • del 键名删除key

    • set runoob “hello”
    • dek runoob
  • flushDB删除当前库数据(flushAll删除所有库数据)

  • 统一密码管理,16个库一个密码

  • redis索引从0开始

  • 默认端口6379

Redis数据类型

即value的数据类型

  • String

    • 和Memcached一样的类型,一个key对应一个value
    • 二进制安全的,即string可以包含任何数据,如jpg图片或者序列化的对象
    • 字符串value最多可以是512M
  • Hash哈希

    • 类似java中的Map< String,Object>
    • 键值对集合
    • string类型的field和value的映射表,适合用于存储对象
      • 命令HMset Hget
        • HMSET runoob field1 “h1” field2 “h2”
        • HGET runoob field1
        • del runoob
  • List列表

    • 简单的字符串列表
    • 按照插入顺序排序,可以添加到头或尾
  • Set集合

    • redis的set是String类型的无序集合。通过HashTable实现的
  • Zset有序集合(Sorted Set)

    • 不允许重复的成员
    • 每个元素都会关联一个double类型的分数
    • 通过分数为集合中成员进行从小到大的排序
    • zset的成员是惟一的,但分数可以重复

Redis命令

key关键字

  • keys *:查询所有key
  • exists (key) keyname :判断某个key是否存在
  • move keyname db:将当前库的key移到db库
  • expire keyname 秒:为给定的key设置过期时间
  • ttl keyname:查看还有多少秒过期,-1表示永不过期,-2表示已经过期
  • type keyname查看你的key所存储的值的类型(五大数据类型)
  • del keyname

String字符串

  • get/set/sppend/strlen
    • set k1 v1
    • get k1
    • append k1 123
    • strlen k1:5
  • incr/decr/incrby/decrby 数字类型才能进行加减
    • set k1 1
    • incr k1:单路递增
    • decr k1:单路递减
    • incrby k1 3:多路递增
    • decrby k1 3:多路递减
  • getrange/setrange 获得区间范围的值
    • set k1 abc123
    • getrange k1 0 -1:取全部,左闭右闭
    • getrange k1 0 2:返回abc
    • setrange k1 3 0:返回6,k1为 abc023
    • setrange k1 3 0000:返回7,k1为abc0000
  • setex(set with expire)/setnx(set if not exist)
    • setex k1 10 v1:设值并设置过期时间
    • setnx k1 v11:已存在,设值失败
  • mget/mset/msetnx(多值设置)
    • mset k1 v1 k2 v2 k3 v3
    • mget k1 k2 k3

List列表

单值多value

实际上是一个字符串链表,left right都可以插入

如果键不存在,创建新的链表

已存在,新增内容

值全部移除,对应的键也就消失

  • lpush/rpush/lrange
    • lpush list1 1 2 3 4 5
    • lrange list1 0 -1:顺序显示5 4 3 2 1
    • lpush list2 1 2 3 4 5
    • lrange list1 0 -1:顺序显示1 2 3 4 5
  • lpop/rpop:左右移出元素
  • lindex:按照索引下标获得元素
  • llen:返回list长度
  • lrem keyname N value:删除N个value
    • rpush list1 1 1 1 2 2 2 3 3 3
    • lrem list1 2 3:删除2个3
    • lrange list1 0 -1:顺序显示1 1 1 2 2 3
  • ltrim keyname 开始index 结束index,截取指定范围的值后再赋值给key(左闭右闭)
    • rpush list1 1 2 3 4 5
    • ltrim list1 3 4
    • lrange list1:顺序显示4 5
  • rpoplpush
    • rpush list1 1 2 3
    • rpush list2 4 5 6
    • rpoplpush list1 list2
    • lrange list2 0 -1:顺序显示3 4 5 6
  • lset keyname index value 设置某个索引value
    • rpush list1 1 2 3
    • lset list1 1 x
    • lrange list1 0 -1:顺序显示1 x 3
  • linsert keyname before/after value1 value2前后插值
    • linsert list1 before x java
    • lrange list1 0 -1:顺序显示1 java x 2

Set集合

单值多value

  • sadd/smembers/sismember

    • sadd set1 0 1 2 3 3
    • smembers set1:顺序显示1 2 3
    • sismeber set1 x:查看set1中是否有x
  • scard 获取集合里面的元素个数

  • srem keyname value 删除集合中元素

  • srandmember keyname N 随机出集合中N个数

  • spop keyname 随机出栈

  • smove key1 key2 key1中某个值:将key1中某个值赋给key2

  • sdiff/sinter/sunion 差交并

Hash哈希

KV模式不变,但value是一个键值对

  • hset/hget/hmset/hmget/hgetall/hdel

    • hset user name mike
    • hget user name
    • hmset customer id 1 name lucy age 26
    • hmget customer id name age
    • hgetall customer
    • hdel user name
  • hlen 返回hash中键值对个数

  • hexists keyname key

    • hexists customer id:返回1
  • hkeys/hvals keyname:返回hash的键集合和值集合

  • hincrby/hincrbyfloat:自增

    • hincrby customer age 2

Zset有序集合

  • zadd/zrange
    • zadd zset01 60 v1 70 v2 80 v3
    • zrange zset01 0 -1 (withsocres)
  • zrangebyscore keyname 开始score 结束score:取分数范围元素
  • zrem keyname 某score对应的value值:删除对应元素
  • zcard/zcount/zrank/zscore
    • zcard keyname 返回zset元素个数
    • zcount zset01 60 70 :返回分数区间元素个数
    • zrank zset01 v3:获得下标值,返回2
    • zscore zset01 v2:获得分数,返回70
  • zrevrank 逆序获得下标值
    • zrevrank zset01 v3:返回0
  • zrevrange 逆序输出
  • zrevrangebyscore zset01 80 60:逆序输出分数区间元素

Redis配置

/opt/redis-xx-xx/redis.config

配置详解

Redis持久化

持久化:将内存的数据写到磁盘上去,防止服务器宕机内存数据丢失

RDB

Redis DataBase

RDB文件:dumn.rdb

功能函数rdbSave生成RDB文件和rdbLoad从文件加载到内存中。

利用fork命令的copy on write机制,在生成快照时,将当前进程fork出一个子进程,然后在子进程中循环所有数据,将数据写成RDB文件替换旧的RDB文件进行持久化。恢复时将快照文件直接读取到内存里。

缺点:数据库出问题,最后一次持久化后的数据可能丢失

应用场景

整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能
如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方
式要比AOF方式更加的高效。

触发机制

RDB文件是整个内存压缩过的snapshot快照,RDB的数据结构可以配置复合 的默认快照触发条件

  • save < seconds> < changes>

    • save 900 1 (15min修改过1次)

    • save 300 10 (5min修改过10次)

    • save 60 10000 (1min修改过10000次)

    • save " " 禁用

save/bgsave命令可立即备份(/usr/local/bin)

  • save:只管保存,其他不管,全部阻塞
  • bgsave:Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求,可以通过lastsave命令获得最后一次成功执行快照的时间
  • 执行flushall命令,也会产生dumo.rdb文件,但里面是空的,无意义

动态停止RDB保存规则的方法:redis-cli config set save " "

总结
  • RDB保存RDB文件时,父进程只需要fork出一个子进程,持久化全部由子进程完成,父进程不需要做其它IO操作。RDB持久化方式可以最大化redis的性能
  • 与AOF相比,在恢复大的数据集时,RDB方式会更快一点
  • 数据丢失风险大,完成性不保证
  • 数据集较大时,fork过程非常耗时,可能导致Redis在毫秒级不能响应客户端请求

AOF

Append Only File

AOF文件:appendonly.aof

配置位置:redis.config中 appendonly no

将Redis执行的每次写命令记录到独立的日志文件中,Redis重启时再次执行AOF文件中的命令恢复数据

注意:写命令包括flushall

使用AOF时,如果同时存在dump.rdb和appendonly.aof时,可以共存,先加载appendonly.aof

修复aof文件:redis-check-aof --fix appendonly.aof

配置之Appendfsync
  • Always:同步持久化,性能较差,但完整性好
  • Everysec:默认,异步操作,每秒记录,如果一秒内宕机,有数据丢失
  • no:从不同步
重写机制(Rewrite)
  • AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,
    当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,
    只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof

  • 重写原理:

    AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),
    遍历新进程的内存中数据,每条记录有一条的Set语句。重写aof文件的操作,并没有读取旧的aof文件,
    而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似

  • 触发机制:Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发

总结
  • 每修改同步:appendfsync always 同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好

  • 每秒同步:appendfsync everysec 异步操作,每秒记录 如果一秒内宕机,有数据丢失

  • 不同步:appendfsync no 从不同步

  • 相同数据集而言aof文件要远大于rdb文件,恢复速度慢于rdb

  • AOF运行效率慢于RDB,每秒同步策略好,不同步效率与RDB相同

对比使用

  • RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储

  • AOF持久化方式记录每次对服务器的写操作,当服务器重启时重写执行这些命令恢复数据。文件追加方式记录,文件过大时支持后台重写

  • 只做缓存,可以不使用任何持久化方式

  • 同时开启两种持久化方式

    • redis重启时优先载入AOF文件来恢复原始的方式,因为AOF文件保存的数据集更加完整
    • RDB不实时,但更适合用于备份数据库(AOF在不断变化不好备份)

Redis的事务

可以一次执行多个命令,本质是一组命令的集合。

一次事务中的所有命令都会序列化,按顺序地串行化执行而不会被其他命令插入,不允许加塞

一次队列中,一次性、顺序性、排他性地执行一系列命令

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

  • 批量操作在发送 EXEC 命令前被放入队列缓存。
  • 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
  • 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

一个事务从开始到执行会经历以下三个阶段:

  • 开始事务。
  • 命令入队。
  • 执行事务。

事务命令

序号 命令及描述
1 DISCARD 取消事务,放弃执行事务块内的所有命令。
2 EXEC 执行所有事务块内的命令。
3 MULTI 标记一个事务块的开始。
4 UNWATCH 取消 WATCH 命令对所有 key 的监视。
5 [WATCH key key …] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

正常执行

redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> set a aaa
QUEUED
redis 127.0.0.1:6379> set b bbb
QUEUED
redis 127.0.0.1:6379> set c ccc
QUEUED
redis 127.0.0.1:6379> exec
1) OK
2) OK
3) OK

放弃事务

redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> set a a4
QUEUED
redis 127.0.0.1:6379> discard
OK

全体连坐

一次事务中出现错误(语法出现错误),事务内所有命令执行失败,exec报错所有语句得不到执行

部分支持事务

语法本身没有错误,但适用对象错误,例如incr ,exec会执行正确的语句,并跳过有问题的语句

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

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

watch监控

乐观锁机制,对key开启监控后,如果另一线程对key进行修改,当前线程开启事务multi,对key进行修改,exec执行事务失败。

监视一个或多个key,如果在事务执行之前这些key被其他命令所动,那么事务将被打断

 redis 127.0.0.1:6379> set k1 v1
 redis 127.0.0.1:6379> watch k1
 redis 127.0.0.1:6379> multi
 OK
 
 此时另一个终端进行操作
 
 redis 127.0.0.1:6379> set k1 v2
 OK
 
 执行完毕后,当前终端继续执行
 redis 127.0.0.1:6379> set k1 k2
 QUEUED
 redis 127.0.0.1:6379> exec
 (nil)
 事务失败

unwatch取消对所有key的监控,一旦执行了exec之前加的监控锁都被取消

Redis的发布和订阅

进程间的通信方式:消息队列,管道,套接字,共享内存,信号量

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。

Redis 客户端可以订阅任意数量的频道。

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

Redis知识笔记及命令全_第1张图片Redis知识笔记及命令全_第2张图片


实例

以下实例演示了发布订阅是如何工作的。在我们实例中我们创建了订阅频道名为 redisChat:

redis 127.0.0.1:6379> SUBSCRIBE c1 c2 c3

Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "c1"
3) (integer) 1
1) "subscribe"
2) "c2"
3) (integer) 1
1) "subscribe"
2) "c3"
3) (integer) 1

现在,我们先重新开启个 redis 客户端,然后在同一个频道 redisChat 发布两次消息,订阅者就能接收到消息。

redis 127.0.0.1:6379> PUBLISH c1 "message to c1"

(integer) 1

redis 127.0.0.1:6379> PUBLISH c2 "message to c2"

(integer) 1

# 订阅者的客户端会显示如下消息
1) "message"
2) "c1"
3) "message to c1"
1) "message"
2) "c2"
3) "message to c2"

Redis 发布订阅命令

下表列出了 redis 发布订阅常用命令:

序号 命令及描述
1 [PSUBSCRIBE pattern pattern …] 订阅一个或多个符合给定模式的频道。
2 [PUBSUB subcommand argument [argument …]] 查看订阅与发布系统状态。
3 PUBLISH channel message 将信息发送到指定的频道。
4 [PUNSUBSCRIBE pattern [pattern …]] 退订所有给定模式的频道。
5 [SUBSCRIBE channel channel …] 订阅给定的一个或多个频道的信息。
6 [UNSUBSCRIBE channel [channel …]] 指退订给定的频道。

Redis复制

也就是我们所说的主从复制,主机数据更新后根据配置和策略,
自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主

作用

  • 读写分离
  • 异地容灾

例:

配置6379 6380 6381端口的redis主机

通过info replication指令查看三个redis主机信息,role均为master

如在6379进行设值

redis 127.0.0.1:6379> set k1 v1
OK

另外两个转为6379的从库,配置命令slaveof 主库IP 主库端口

redis 127.0.0.1:6379> slaveof 127.0.0.1 6379
OK


redis 127.0.0.1:6381> slaveof 127.0.0.1 6379
OK

6379再次设值

redis 127.0.0.1:6379> set k2 v2
OK

此时两个从库数据已经从主库中全部复制过来,且执行info replication指令发现从库role变为slave

一主二从

读写分离只有主机能写,从机只能读

主机SHUTDOWN后,从机原地待命,角色不变;主机启动,恢复原状

从机SHUTDOWN,与master断开,每次断开之后都需要重新连接,除非配置进redis.config文件

薪火相传

  • 上一个Slave可以是下一个slave的Master,Slave同样可以接收其他
    slaves的连接和同步请求,那么该slave作为了链条中下一个的master,
    可以有效减轻master的写压力

  • 中途变更转向:会清除之前的数据,重新建立拷贝最新的

  • slaveof 新主库IP 新主库端口

反客为主

通过命令SLAVEOF no one可以配置为master角色

复制原理

复制原理
slave启动成功连接到master后会发送一个sync命令
Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,
在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步
全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步
但是只要是重新连接master,一次完全同步(全量复制)将被自动执行

哨兵模式(sentinel)

能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库

自定义sentinel.config文件,配置哨兵,填写内容

sentinel monitor 被监控数据库名字(自定义) 127.0.0.1 6379 1(票数)

启动哨兵

redis-sentinel /myredis/sentinel.conf 

之前的master重启回来变为从库

复制延迟

由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。

你可能感兴趣的:(笔记,复习,面试)