redis 有哪些数据结构
String
*** 字符串类型是 redis 最基础的数据结构,首先键是字符串类型,而且其他几种结构都是在字符串类型基础上构建的 字符串类型实际上可以是字符串、数字、二进制(图片、音频),单最大不能超过 512M,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个value。 SET 和 GET 命令
1 SET key key-value设置指定 key 的值
2 GET key 获取指定 key 的值。
3 GETRANGE key start end 返回 key 中字符串值的子字符
4 GETSET key value 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
5 GETBIT key offset 对 key 所储存的字符串值,获取指定偏移量上的位(bit)。
6 MGET key1 [key2..] 获取所有(一个或多个)给定 key 的值。
7 SETBIT key offset value 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
8 SETEX key seconds value 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。
9 SETNX key value 只有在 key 不存在时设置 key 的值。
10 SETRANGE key offset value 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始。
11 STRLEN key 返回 key 所储存的字符串值的长度。
12 MSET key value [key value ...] 同时设置一个或多个 key-value 对。
13 MSETNX key value [key value ...] 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。
14 PSETEX key milliseconds value 这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。
15 INCR key 将 key 中储存的数字值增一。
16 INCRBY key increment 将 key 所储存的值加上给定的增量值(increment) 。
17 INCRBYFLOAT key increment 将 key 所储存的值加上给定的浮点增量值(increment) 。
18 DECR key 将 key 中储存的数字值减一。
19 DECRBY key decrement key 所储存的值减去给定的减量值(decrement) 。
20 APPEND key value 如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾。
使用场景:
缓存 字符串最经典的使用场景,redis 作为缓存层,mysql 作为存储层,绝大部分请求数据都是 redis 中获取,由于 redis 具有支撑高并发特性, 所以缓存通常能起到加速读写和降低后端压力的作用
计数器 许多应用都会使用 redis 作为技术的基础工具,它可以实现快速技术、查询缓存的功能。
共享 session 处于负载均衡的考虑,分布式服务会将用户信息的访问均衡到不同服务器,用户刷新一次访问可讷讷个会需要重新登录,为了避免这个问题 可以使用 redis 将用户 session 集中管理,在这种模式下只要保证 redis 的高可用和扩展性,每次获取用户更新或查询登录信息都直接从 redis 中集中获取
限速 出于安全考虑,每次进行登录时让用户输入手机验证码,为了短信接口不被频繁访问,会限制用户每分钟获取验证码的频率
Hash
在 redis 中哈希类型是指键本身又是一种键值对结构,如 value = {{field1,value1}…{fieldn,valuen}}
是一个键值(key=>value)对集合,hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象 命令HMSET, HGET 命令
使用场景:
- 哈希结构相对于字符串序列化缓存信息更加直观,并且在更新操作上更加便捷。
1 HDEL key field1 [field2] 删除一个或多个哈希表字段
2 HEXISTS key field 查看哈希表 key 中,指定的字段是否存在。
3 HGET key field 获取存储在哈希表中指定字段的值。
4 HGETALL key 获取在哈希表中指定 key 的所有字段和值
5 HINCRBY key field increment 为哈希表 key 中的指定字段的整数值加上增量 increment 。
6 HINCRBYFLOAT key field increment 为哈希表 key 中的指定字段的浮点数值加上增量 increment 。
7 HKEYS key 获取所有哈希表中的字段
8 HLEN key 获取哈希表中字段的数量
9 HMGET key field1 [field2] 获取所有给定字段的值
10 HMSET key field1 value1 [field2 value2 ] 同时将多个 field-value (域-值)对设置到哈希表 key 中。
11 HSET key field value 将哈希表 key 中的字段 field 的值设为 value 。
12 HSETNX key field value 只有在字段 field 不存在时,设置哈希表字段的值。
13 HVALS key 获取哈希表中所有值。
14 HSCAN key cursor [MATCH pattern] [COUNT count] 迭代哈希表中的键值对。
list
列表类型是用来存储多个有序的字符串,列表的每个字符串成为一个元素,一个列表最多可以存储 2 的 32 次方减 1 个元素。在 redis 中,可以对列表 插入(push)和弹出(pop),还可以获取指定范围的元素列表。列表是一种比较灵活的数据结构,它可以充当栈和队列的角色。 使用场景:
消息队列 redis 的 lpush+brpop 命令组合就可以实现阻塞队列,生产者客户端是用 lpush 从列表左侧插入元素,多个消费者客户端使用 brpop 命令阻 塞式的抢列表尾部的元素,多个客户端保证了消费的负载均衡的高可用性。
使用技巧列表
lpush+lpop=Stack(栈) lpush+rpop=Queue(队列) lpush+ltrim=Capped Collection(有限集合) lpush+brpop=Message Queue(消息队列)
1 BLPOP key1 [key2 ] timeout 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
2 BRPOP key1 [key2 ] timeout 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
3 BRPOPLPUSH source destination timeout 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
4 LINDEX key index 通过索引获取列表中的元素
5 LINSERT key BEFORE|AFTER pivot value 在列表的元素前或者后插入元素
6 LLEN key 获取列表长度
7 LPOP key 移出并获取列表的第一个元素
8 LPUSH key value1 [value2] 将一个或多个值插入到列表头部
9 LPUSHX key value 将一个值插入到已存在的列表头部
10 LRANGE key start stop 获取列表指定范围内的元素
11 LREM key count value 移除列表元素
12 LSET key index value 通过索引设置列表元素的值
13 LTRIM key start stop 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
14 RPOP key 移除列表的最后一个元素,返回值为移除的元素。
15 RPOPLPUSH source destination 移除列表的最后一个元素,并将该元素添加到另一个列表并返回
16 RPUSH key value1 [value2] 在列表中添加一个或多个值
17 RPUSHX key value 为已存在的列表添加值
Set(集合)
Redis 的 Set 是 string 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。sadd key member ,用于点赞、收藏
1 SADD key member1 [member2] 向集合添加一个或多个成员
2 SCARD key 获取集合的成员数
3 SDIFF key1 [key2] 返回第一个集合与其他集合之间的差异。
4 SDIFFSTORE destination key1 [key2] 返回给定所有集合的差集并存储在 destination 中
5 SINTER key1 [key2] 返回给定所有集合的交集
6 SINTERSTORE destination key1 [key2] 返回给定所有集合的交集并存储在 destination 中
7 SISMEMBER key member 判断 member 元素是否是集合 key 的成员
8 SMEMBERS key 返回集合中的所有成员
9 SMOVE source destination member 将 member 元素从 source 集合移动到 destination 集合
10 SPOP key 移除并返回集合中的一个随机元素
11 SRANDMEMBER key [count] 返回集合中一个或多个随机数
12 SREM key member1 [member2] 移除集合中一个或多个成员
13 SUNION key1 [key2] 返回所有给定集合的并集
14 SUNIONSTORE destination key1 [key2] 所有给定集合的并集存储在 destination 集合中
15 SSCAN key cursor [MATCH pattern] [COUNT count] 迭代集合中的元素
zset(有序集合)
是string类型的有序集合,用在排名方面
Stream
Redis Stream 主要用于消息队列(MQ,Message Queue),Redis 本身是有一个 Redis 发布订阅 (pub/sub) 来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。
消息队列相关命令:
XADD - 添加消息到末尾
XTRIM - 对流进行修剪,限制长度
XDEL - 删除消息
XLEN - 获取流包含的元素数量,即消息长度
XRANGE - 获取消息列表,会自动过滤已经删除的消息
XREVRANGE - 反向获取消息列表,ID 从大到小
XREAD - 以阻塞或非阻塞方式获取消息列表
消费者组相关命令:
XGROUP CREATE - 创建消费者组
XREADGROUP GROUP - 读取消费者组中的消息
XACK - 将消息标记为"已处理"
XGROUP SETID - 为消费者组设置新的最后递送消息ID
XGROUP DELCONSUMER - 删除消费者
XGROUP DESTROY - 删除消费者组
XPENDING - 显示待处理消息的相关信息
XCLAIM - 转移消息的归属权
XINFO - 查看流和消费者组的相关信息;
XINFO GROUPS - 打印消费者组的信息;
XINFO STREAM - 打印流信息
HyperLogLog
1 PFADD key element [element ...] 添加指定元素到 HyperLogLog 中。
2 PFCOUNT key [key ...]返回给定 HyperLogLog 的基数估算值。
3 PFMERGE destkey sourcekey [sourcekey ...]
4 将多个 HyperLogLog 合并为一个 HyperLogLog
GEO
Redis GEO 主要用于存储地理位置信息,并对存储的信息进行操作
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
redis 是单线程的么,为什么
因为 CPU 并不是 Redis 的瓶颈,Redis 的瓶颈最有可能是机器内存或者网络带宽。既然单线程容易实现,而且 CPU 不会成为瓶颈,那么久顺理成章的采用了单 线程的方案。 当然单个 Redis 进程是没办法使用多核的 ,但是它来就不是非常计算密集型的服务。如果单核性能不够用,可以多开几个进程。redis可以原子操作一个线程不受其他打断,memecached是多线程会相互影响。
Redis 如何实现持久化?
- RDB 持久化,将 redis 在内存中的的状态保存到硬盘中,相当于备份数据库状态
- 1AOF 持久化(Append-Only-File),AOF 持久化是
通常在web开发中使用缓存,不得不说到Redis 和 Memcached 的区别
- Redis 和 Memcache 都是将数据存放在内存中,都是内存数据库。但是 Memcache 还可以缓存其他东西,比如图片、视频
- Redis 不只支持简单的 k/v 类型的数据,同时还提供 list、set、hash 等数据结构的存储
- 虚拟内存,当物理内存用完时 Redis 可以将一些很久没有用到的 value 交换到磁盘
- 过期策略,memcache 在 set 时就指定,例如 set key1 0 0 8 即永不过期,redis 可以通过 expire
设定,例如:expire name 10 - 分布式,设定 memcache 集群,利用 magent 做一主多从;redis 也可以做一主多从。
- 存储安全,memcache 挂掉后,数据没了;redis 可以定期保存在磁盘(持久化)
- 灾难恢复,memcache 挂掉后数据不可恢复;
- redis 数据丢失后可以通过 aof 恢复 redis 支持数据的备份,即 master-slave 模式的数据备份
- 应用场景不同:redis 除了可以做 nosql 数据库之外,还能做消息队列、数据堆栈和数据缓存等。memcache 适合于缓存 sql
语句、数据集、用户临 时性数据、延迟查询数据和 session 等 - Redis 支持更加丰富的数据存储类型,String、Hash、List、Set 和 Sorted Set。Memcached
仅支持简单的 key-value 结构。 - Memcached key-value 存储比 Redis 采用 hash 结构来做 key-value 存储的内存利用率更高。
- Redis 提供了事务的功能,可以保证一系列命令的原子性
- Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中
- Redis 只使用单核,而 Memcached 可以使用多核,所以平均每一个核上 Redis 在存储小数据时比 Memcached 性能更高。
分布式存储
- redis支持master-slave复制模式
- memcache可以使用一致性hash做分布式
value大小不同
memcache是一个内存缓存,key的长度小于250字符,单个item存储要小于1M,不适合虚拟机使用
数据一致性不同
- Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。
- redis使用的是单线程模型,保证了数据按顺序提交。
- memcache需要使用cas保证数据一致性。CAS(Check and
Set)是一个确保并发一致性的机制,属于“乐观锁”范畴;原理很简单:拿版本号,操作,对比版本号,如果一致就操作,不一致就放弃任何操作
cpu利用
redis单线程模型只能使用一个cpu,可以开启多个redis进程