Redis常用数据类型
Redis是NoSQL型数据库,数据都在内存中,支持持久化,支持多种数据结构的存储,如String、list、set、hash、zset。一般作为缓存数据库辅助持久化的数据库。本篇记录基本概念和操作,关于持久化、主从复制、事务、集群等内容的学习查看官方文档。
Redis安装配置
Redis安装
- 下载官网最新redis压缩包,上传到虚拟机中并解压
 - 安装c语言编译环境:yum install gcc
 - 进入redis解压后目录,make进行编译
 - make install
 - 安装目录在/usr/local/bin,包括
- redis-benchmark:性能测试工具
 - redis-check-aof:修复有问题的AOF文件
 - redis-check-dump:修复有问题的dump.rdb文件
 - redis-sentinel:Redis集群使用
 - redis-server:Redis服务器启动命令
 - redis-cli:客户端操作入口
 
 
Redis启动
- 备份redis.conf到其它目录下,如cp redis.conf /etc/
 - 修改备份文件中daemonize no改为yes,可以让服务在后台启动
 - 启动:redis-server /etc/redis.conf
 - 连接:redis-cli
 
五大数据类型
Redis默认16个数据库,从0到15,select dbid 可以切换数据库,所有库统一密码。
dbsize:查看当前库的key数量
flushdb:清空当前库
flushall:清空所有库(慎用)
Redis是单线程+多路IO复用技术
String
- keys *:查看当前库所有key
 - exists key:判断某个key是否存在
 - type key:查看key是什么类型
 - del key:删除指定key的数据
 - unlink key:根据value选择非阻塞删除
 - expire key n:为key设置过期时间,ttl key可以查看过期时间,-1表示永不过期,-2表示已过期
 - set key value:添加键值对
 - get key:查询对应键值
 - append key value:将给定的value追加到原值末尾
 - strlen key:获取值的长度
 - setnx key value:只有key不存在时,设置key值成功
 - incr/decr key:将 key中储存的数字值增1/减1
- 该操作是原子操作,不会被线程调度机制打断,一旦开始,就一直运行到结束,中间不会切换到另一个线程,Redis单命令的原子性得益于Redis的单线程。
 
 - incrby/decrby key <步长>:将key中存储数值增减步长
 - mset key1 value1 key2 value2 …:同时设置多个key-value
 - mget key1 key2…:同时获取多个value
 - msetnx key1 value1 key2 value2:同时设置多个key-value,当且仅当所有key不存在成功。
- 原子性:有一个key存在则都设置失败
 
 - getrange key start end :获取值的范围,两端都闭
 - setrange key offset value:从offset开始,用value覆盖原字符串
 - setex key 过期时间 value:设置键值同时设置过期时间,单位秒
 - getset key value:获取key对应旧值,同时设置新值为value
 
数据结构:简单动态字符串(Simple Dynamic String,缩写SDS),是可以修改的字符串,内部结构实现上类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。
![]()
如图中所示,内部为当前字符串实际分配的空间capacity一般要高于实际字符串长度len。当字符串长度小于1M时,扩容都是加倍现有的空间,如果超过1M,扩容时一次只会多扩1M的空间。需要注意的是字符串最大长度为512M。
List
- lpush/rpush key value1 value2…:从左边/右边插入一个/多个值
 - lpop/rpop key:从左边/右边取出一个值。值取完,键也不存在了
 - rpoplpush key1 key2:从key1列表右侧取出一个值,查到key2的左侧
 - lrange key start stop:按照索引下标获得元素(从左到右),0 -1表示所有
 - lindex key index:按照索引下标获取元素
 - llen key:获得列表长度
 - linsert key before/after value newvalue:在value前/后插入newvalue
 - lset key index value:将列表key 下标为index的值替换成value
 
数据结构:快速链表quickList。在列表元素较少的情况下会使用一块连续的内存存储,这个结构是ziplist,也即是压缩列表。它将所有的元素紧挨着一起存储,分配的是一块连续的内存。当数据量比较多的时候才会改成quicklist。
![]()
Redis将链表和ziplist结合起来组成了quicklist。也就是将多个ziplist使用双向指针串起来使用。这样既满足了快速的插入删除性能,又不会出现太大的空间冗余。
Set
- sadd key value1 value2…:将元素加入集合key中,已存在的元素被忽略
 - smembers key:查询该集合所有值
 - sismember key value:判断集合key是否含有该value值
 - scard key:返回集合元素个数
 - srem key value1 value2…:删除集合中的元素
 - spop key:从集合中随机去除一个值
 - srandmember key n:从集合中随机取出n个值。不会删除
 - smove key1 key2 value:把key1集合的value移到key2中去
 - sinter k1 k2:返回两集合交集
 - sunion k1 k2:返回两集合并集
 - sdiff k1 k2:返回两集合差集,在k1中不在k2中的
 
数据结构:Set数据结构是dict字典,字典是用哈希表实现的。Java中HashSet的内部实现使用的是HashMap,只不过所有的value都指向同一个对象。Redis的set结构也是一样,它的内部也使用hash结构,所有的value都指向同一个内部值。
Hash
Redis hash是一个String类型的field和value的映射表,适合用于存储对象
- hset key field value field value…:设置key中的field键为value
- 如hset user id 1 name jack age 20
 
 - hget key field:从key中取出键为field的值
 - hdel key field1 field2…:删除key中的field域
 - hexists key field:判断key中是否存在域field
 - hkeys key:列出该key的所有field
 - hvals key:列出该key的所有value
 - hincrby key field increment:为key中field域加上increment
 - hsetnx key field value:将key中域field值设置为value,仅当field域不存在时成功
 
数据结构:Hash类型对应的数据结构是两种:ziplist(压缩列表),hashtable(哈希表)。当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable。
Zset(有序集合)
与普通集合set非常相似,是一个没有重复元素的字符串集合。不同之处是有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员
- zadd key score1 value1 score2 value2…:将value值加入有序集合key中,并指定score值
 - zrange key start stop [withscores]:返回有序集合中,下标在[start,stop]之间的元素
 - zrangebyscore key min max:返回有序集 key 中,所有 score 值介于 min 和 max 之间的成员
 - zincrby:为元素加上增量
 - zrem key value:删除该集合指定元素
 - zcount key min max:返回该集合分数区间内元素个数
 - zrank key value:返回该值排名,从0开始
 
zset结构同时包含一个字典和一个跳跃表,跳跃表按score从小到大保存所有集合元素。字典保存着从member到score的映射。这两种结构通过指针共享相同元素的member和score,不会浪费额外内存。
跳跃表的结构:跳跃表
Jedis操作Redis
依赖
1  | <dependency>  | 
连接Redis
1  | public class JedisDemo {  | 
Key
1  | jedis.set("k1", "v1");  | 
String
1  | jedis.mset("str1","v1","str2","v2","str3","v3");  | 
List
1  | jedis.lpush("k1","v1","v2");  | 
Set
1  | jedis.sadd("orders", "order01");  | 
Hash
1  | jedis.hset("hash1","userName","lisi");  | 
Zset
1  | jedis.zadd("zset01", 100d, "z3");  |