查漏补缺系列之《Redis实战》 - redis基础

260 阅读7分钟

名词

  • ACID: atomicity原子性、consistency一致性、isolation隔离性、durability耐久性,一个数据库实现可靠的数据事务需满足的性质。

特点

  • 速度快: 使用内存存储的非关系型数据库。
  • 原子性: 当命令正在读取或修改数据的时候,其他客户端不能读取或修改相同的数据。

数据类型

结构类型结构存储的值场景
STRING字符串、浮点数、整数
LIST一个链表
SET无序去重的集合
HASH包含键值对的无序散列表
ZSET根据分值大小排序且去重的有序映射排行榜(分值越小,排行靠前)

指令

SETRING 字符串

  • GET
  • SET
  • DEL
指令描述
APPEND key value将值追加到字符串尾部
GETRANGE key value将值追加到字符串尾部

LIST 列表

redis使用双链表表示列表

  • RPUSH
  • LPUSH
  • LRANGE
  • LINDEX 获取给定位置的元素

SET 集合

redis通过配置可设置集合使用整数集合表示的限制条件,超出限制则使用散列表表示。

指令描述
SADD key item1 [item2 ...]增加一个或多个元素
SMEMBERS key返回集合包含的所有元素
SISMEMBER key item是否在集合中
SREM key item移除元素
SCARD key返回集合包含元素数量
SRANDMEMBER key [count]随机返回count个元素,整数不重复,负数会重复
SPOP key随机移除一个元素
SMOVE source-key dest-key item将item从source-key集合中移除,并移入dest-key的集合下
SDIFF key1 [key2 ...]返回存在于key1,不存在于其他集合的元素(差集)
SDIFFSTORE dest-key key1 [key2 ...]将存在于key1,不存在于其他集合的元素,存储到dest-key去(差集)
SINTER key1 [key2 ...]返回同时存在于所有集合的元素(交集)
SINTERSTORE dest-key key1 [key2 ...]返回同时存在于所有集合的元素,存储到dest-key去(交集)
SUNION key1 [key2 ...]返回那些至少存在于一个集合中的元素(并集)
SUNIONSTORE dest-key key1 [key2 ...]返回那些至少存在于一个集合中的元素,存储到dest-key去(并集)

HASH 散列

redis使用散列表表示散列

指令描述
HSET key field1 value1 [field2 value2]为散列里面的一个或多个键设置值
HGET key field从散列里获取键的值
HMGET key field1 [field2]从散列里获取键的值
HDEL key field1 [field2]移除散列一个或多个键值对
HLEN key获取散列键值对数量
HEXISTS key filed检查给定键是否存在于散列中
HKEYS key获取散列包含的所有键
HVALS key获取散列包含的所有值
HGETALL key获取散列所有键值
HINCRBY key field increment给散列指定键的值加上整数increment
HINCRBYFLOAT key filed increment给散列指定键的值加上浮点数increment

ZSET 有序集合

redis通过散列表加上跳跃表表示有序集合

指令描述
ZADD key score member [score2 member2 ...]将带有一定分值的成员添加到有序集合
ZREM key member1 [member2 ...]移除成员
ZCARD key返回有序集合成员数量
ZINCRBY key increment member将member成员的分值加上increment
ZCOUNT key min max返回分值介于min和max之间的成员数量
ZSCORE key member返回成员member的分值
ZRANK key member分值升序排序,返回成员member在有序集合之中的排名
ZRANGE key start stop [WITHSCORES]分值升序排序,返回排名介于start和stop之间的成员,如果给了WITHSCORES参数,则将成员分值一并返回
ZREVRANK key member分值升序排序,返回成员member在有序集合之中的排名
ZREVRANGE key start stop [WITHSCORES]分值降序排序,返回排名介于start和stop之间的成员,如果给了WITHSCORES参数,则将成员分值一并返回
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]分值升序排序,返回分值介于min和max之间的成员,如果给了WITHSCORES参数,则将成员分值一并返回
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]分值降序排序,返回分值介于max和min之间的成员,如果给了WITHSCORES参数,则将成员分值一并返回
ZREMRANGEBYSRANK key start stop分值升序排序,移除排名介于start和stop之间的成员
ZREMRANGEBYSCORE key min max分值升序排序,移除排名介于min和max之间的成员
`ZINTERSTORE dest-key key-count key1 [key2 ...] [WEIGHTS weight1 [weight2]] [AGGREGATE SUMMINMAX]`有序集合交集运算
`ZUNIONSTORE dest-key key-count key1 [key2 ...] [WEIGHTS weight1 [weight2]] [AGGREGATE SUMMINMAX]`有序集合并集运算

其他命令

指令描述
`SORT key [BY pattern] [LIMIT offset count] [GET pattern] [ASCDESC] [ALPHA] destination`排序
发布与订阅
指令描述
SUBSCRIBE channel [channel]订阅给定一个或多个频道
UNSUBSCRIBE [channel... [channel2 ...]]退订给定一个或多个频道,没有给定则退订所有频道
PUBLISH channel message向给定频道发送消息
PSUBSCRIBE pattern1 [pattern2 ...]订阅与给定模式匹配的所有频道
PUNSUBSCRIBE pattern1 [pattern2 ...]退订给定模式匹配的所有坡;频道,没有给定则退订所有频道
事务
指令描述
MULTI事务开始
EXEC执行事务开始后的多个指令
过期
指令描述
PERSIST key移除键的过期时间(s)
TTL key查看键距离过期剩余时间(s)
EXPIRE key seconds给定键在指定秒数后过期
EXPIREAT key timestamp给定键在给定UNIX时间戳(s)后过期
PTTL key查看键距离过期剩余时间(ms)
PEXPIRE key milliseconds给定键在指定毫秒数后过期
PEXPIREAT key timestamp-milliseconds给定键在给定UNIX时间戳(ms)后过期

数据持久化

方法

  • 快照: 把某一时刻所有数据写入硬盘
  • AOF: append-only file,在执行命令时,将被执行的命令写入硬盘

指令

指令描述
BGSAVE创建一个快照。通过fork一个子进程,负责将快照写入硬盘,而父进程继续处理命令。缺点: 速度慢,内存占用大
SAVE创建一个快照。在快照创建完毕前不再响应任何其他指令 。缺点:无法正常执行其他指令
SHUTDOWN执行SAVE后关闭服务器
BGREWRITEAOF移除AOF文件中冗余命令来重写AOF文件,从而减小AOF文件体积,工作原理同BGSAVE
INFO查看服务器当前状态有关信息,如内存占用量、客户端连接数、上次快照后执行的命令数量等,其中aof_pending_bio_fsync为0时,表示服务器将所有数据已持久化到硬盘了

实践

分布式锁

用于解决能够被不同客户端多个进程访问的共享内存数据结构。在数据进行加锁时,程序需通过获取锁来对数据进行排他性访问的能力,才能对数据进行操作,最后还要将锁释放给其他程序。

  • 公平锁:按照申请锁的顺序提供锁
  • 非公平锁: 不按申请锁的顺序提供锁
  • 独享锁:仅允许被一个线程所持有
  • 共享锁:允许多个线程持有
  • 乐观锁:常用于读场景,先操作后拿锁,不等待锁释放
  • 悲观锁:常用于写场景,先拿锁后操作,等待锁释放后拿锁执行,行锁表锁都是用这个
  • 粗粒度锁:通过一个锁,把执行的代码块都锁定
  • 细粒度锁:和粗粒度锁相对
  • 带超时限制特性的锁

信号量

  • 计数信号量: 限定能够同时使用的资源数量。通过时间戳作为有序集合的分值的方式,统计获得锁的用户,移除超时限的用户,剩下拿到锁的用户。缺点是多个客户端时,时间较慢的客户端会偷走时间较快的客户端的信号量。
  • 公平信号量: 通过自增的计数器作为有序集合的分值的方式

细粒度锁

在拥有多个操作分区情况下,如果只有单一一个锁,会阻塞多个请求。为了支持更高并发,减少阻塞,需细化锁的设计

分级锁的设计:

  • Top锁
  • Child锁

使用规则: 在操作开始前,必须先申请得到Top锁来准备获取Child锁,在获取得到Child锁之后,可以再释放Top锁。这里的Child锁,可以理解为就是每个分区锁。这里Top锁的目的是为了保证获取各个分区锁的原子性。

任务队列

通过有序集合,分值为任务执行时间,定时轮询队列,按分值升序排序,小于当前时间的立即执行。

性能优化

事务

一次向Redis发送多条指令

压缩列表

  • 让键名保持简短
  • 使用短结构