Redis概述
传统Java Web项目使用数据库进行存储数据,由于数据库持久化数据主要是面向磁盘,而磁盘的读写速度比较慢,所以当系统中出现访问量瞬间增大的时候,例如抢购秒杀等,数据库往往不能承受而导致系统瘫痪。
为了克服问题,java web项目引入了NoSQL技术。NoSQL工具也是一种数据库,基于内存,并提供一定的持久化功能。使用比较广泛的有Redis和MongoDB。、
Redis的优越性能主要来自3个方面:
1、基于ANSIC语言编写,接近汇编的语言,运行速度很快。
2、基于内存读写。
3、数据库结果只有6种数据类型,数据结构简单,规则少。
Redis的在Java Web的应用主要有两方面:缓存和高速读写。
在开发中,要操作Redis数据库,一般通过Java API或者Spring提供的RedisTemplate。
简介6种数据类型
Redis是一种键值(key-value)数据库,使用key作为索引找到缓存的数据。
当前Redis支持6种数据类型:
- 字符串(String)
- 列表(List)
- 集合(set)
- 哈希(hash)
- 有序集合(zset)
- 基数(HyperLogLog)
Redis提供的6种数据类型,除了提供简单的存储功能,还能对存储的数据进行一些简单的计算。
数据类型 | 数据类型存储的值 | 说明 |
---|---|---|
STRING | 可以保存字符串,整数,浮点数。 | 可以对字符串进行操作,如增加字符或求子串;如果是整数或者浮点数,可以实现计算,比如自增等。 |
LIST | 链表,每个节点都包含一个字符串。 | Redis支持从链表的两端插入或弹出节点,或者通过偏移对它进行裁剪,还可以读取一个或多个节点,根据条件删除或者查找节点等。 |
SET | 无序集合,每个元素都是一个字符串,而且是独一无二各不相同的。 | 可以新增,读取,删除单个元素。检测一个元素是否存在;计算和其他集合的交集,并集,差集等。也可以随机从集合中读取元素。 |
HASH | 类似Java的Map,是一个键值对应的无序列表。 | 可以增删改查单个键值对,也可以获取所有的键值对 |
ZSET | 有序集合,可以包含字符串、整数、浮点数、分值(score),元素的排序根据分值的大小决定。 | 可以增删改查元素,根据分值范围或者成员来获取对应的元素。 |
HyperLogLog | 它的作用是计算重复的值,以确定存储的数量 | 只提供基数运算,不提供返回功能。 |
Redis数据结构
字符串
字符串是最基本的数据结构。以一个键和一个值存储于Redis内部。根据key去找到对应的value。
字符串的一些基本命令如下:
set key value
:设置键值对。
get key
:通过键获取值。
del key
:通过key删除键值对。返回删除数。这个命令是通用命令,在其他数据结构中一样可以使用。
strlen key
:返回key字符串的长度。
getset key value
:修改原来key的对应值,并返回旧值。如果原来key为空,则返回空,并设置新值。
getrange key start end
:获取key的子串,start从0开始,end最多取len-1。
append key value
:将新的字符串value追加到原来key指向的字符串末尾,返回追加后新的value长度。
如果value为数值类型,还有如下命令:
incr key
:原value加1,只能操作整数。
incrby key increment
:原value加上整数increment,只能操作整数。
decr key
:原value减1,只能操作整数。
decrby key decrement
:原value减去整数decrement,只能操作整数。
incrbyfloat key increment
:原value加上浮点数increment,可以操作整数或浮点数。
浮点数不支持incr、incrby、decr、decrby命令。Redis不支持减法、乘法、除法。
哈希
一个key对应一个value,value包括很多键值对。、
哈希的一些基本命令如下:
hdel key field1 [field2...]
:删除字段,可以删除多个。
hexists key field
:判断是否存在field字段。存在返回1,不存在返回0。
hgetall key
:获取所有的键和值。
hincrby key field increment
:给指定字段加上一个整数,要求该字段也是整数。
hincrbyfloat key field increment
:给指定字段加上一个浮点数,要求该字段是数值型。
hkeys key
:获取所有的键。
hlen key
:获取键值对的数量。
hmget key field1 [field2...]
:返回指定键的值,可以是多个。
hmset key field1 value1 [field2 value2...]
:设置多个键值对。
hset key field value
:设置单个键值对。
hsetnx key field value
:当hash结构中不存在对应的键,才设置值。
hvals key
:获取所有的值。
链表
可以存储多个字符串,而且有序。
Redis中的链表是双向的。使用链表意味着读性能的丧失。链表的优势是插入和删除的便利。
常用命令:
lpush key node1 [node2...]
:把节点node1加入最左边,然后再执行node2,依次…
rpush key node1 [node2...]
:把节点node1加入最右边,然后再执行node2,依次…
lindex key index
:读取下标为index的节点,从0开始算。
llen key
:返回链表长度
lpop key
:删除左边第一个节点,并返回。
rpop key
:删除右边第一个节点,并返回。
linsert key before|after pivot node
:插入一个节点,并指定在值为pivot的节点的前面或者后面。
lpushx list node
:如果存在list,则在左边插入节点。
rpushx list node
:如果存在list,则在右边插入节点。
lrange list start end
:获取链表从start到end的节点值,包含start和end。
lrem list count value
:如果count为0,就删除所有值等于value的节点。如果count不是0,先取绝对值abs,然后从左到右删除不大于abs个等于value的节点。
lset key index node
:设置列表下标为index的节点的值为node。
ltrim key start stop
:修剪列表,只保留start到end区间的节点。包含start和end。
操作链表的命令都是进程不安全的。当一个用户操作这些命令的时候,其他用户也可能在操作同一个链表。所以Redis提供了链表的阻塞命令,在执行这些命令的时候,会给链表加锁,保证链表的命令安全,加锁期间其他进程不能再读写该链表。这些命令有:
blpop key timeout
:移出并获取列表的最左边的第一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
brpop key timeout
:移出并获取列表的最右边的第一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
rpoplpush key src dest
:按从左到右的顺序,将一个链表的最后一个元素移出,并插入新元素到最左边。
brpoplpush key src dest timeout
:按从左到右的顺序,将一个链表的最后一个元素移出,并插入新元素到最左边。可以设置超时时间。
集合
集合不是线性结构,是哈希表结构,集合中元素不可以重复,而且是无序的。每一个元素都是String类型的。
常用命令:
sadd key member1 [member2...]
:给键为key的集合增加成员,可以多个。
scard key
:统计键为key的集合成员数。
sdiff key1 [key2]
:两个集合的差集。如果只有一个key,则返回该集合所有元素。
sdiffstore des key1 [key2]
:先求出差集,然后将其保存到des集合中。
sinter key1 [key2]
:求两个集合的交集,如果只有一个key,则返回该集合所有元素。
sinterstore des key1 key2
:先求出交集,然后将其保存到des集合中。
sismember key member
:判断member是否为键key的集合的成员。是返回1,不是返回0。
smembers key
:返回所有集合成员。
smove src des member
:将成员member从集合src迁移到集合des中。
spop key
:随机弹出集合的一个元素。
srandmember key [count]
:随机返回一个或多个元素。不超过count个,如果count为负数,则先求绝对值。如果count大于元素总数,返回整个集合。
srem key member1 [member2...]
:移除集合中的元素。
sunion key1 [key2]
:求两个集合的并集。如果只有一个key,则返回该集合所有元素。
sumionstore des key1 key2
:先求出并集,然后将其保存到des集合中。
有序集合
有序集合与集合类似,和无序集合的区别是每个元素除了值以外,还会多一个分数。分数是一个浮点数,在java中用双精度浮点表示,Redis支持对分数大小排序。
和无序集合一样,每个元素都是唯一的,但对于不同的元素,分数可以一样。
常用命令:
zadd key score1 value1 [score2 value2 ...]
:向有序集合的key增加一个或多个成员元素,如果key不存在,则创建key。
zcard key
:获取key的成员元素数量
zcount key min max
:根据分数区间返回成员列表,范围默认为[min,max],如果需要不包含,则在分数前面加入“(”,不支持”[“。
zincrby key increment member
:给有序集合key的成员值为member的分数增加increment。
zinterstore desKey numKeys key1 [key2 key3 ...]
:求多个有序集合的交集,并将结果存入desKey,numKeys表示有多少个有序集合。
zlexcount key min max
:求有序集合key成员值在min和max的范围。[表示包含该值,(表示不包含。
zrange key start stop [withscores]
:按照分值从小到大返回成员,加入start和stop参数可以截取某一段,如果输入withscores则联通分数一起返回,start和stop表示排序后的下标,从0开始。
zrank key member
:按从小到大求member的下标,排第一的为0。
zrangebylex key min max [limit offset count]
:根据值的范围,从小到大排序,limit可选,当求出范围集合后,产生下标0到n,再根据偏移量offset和限定返回数count,返回对应的成员。min和max借助数学区间表示法。
zrangebyscore key min max [withscores][limit offset count]
:根据分数范围,从小到大排序,输入可选项withscores连同分数一起返回。limit选项参考上一条命令。区间默认包含。不支持"["。
zremrangebyscore key start stop
:根据分数区间进行删除。数学区间表示范围。
zremrangebyrank key start stop
:按照分数从小到大的排序删除,从0开始计算,start和stop表示下标。
zremrangebylex key min max
:按照值得分布进行删除。
zrevrange key start stop [withscores]
:从大到小按分数排序。与zrange相反。
zrevrangebyscore key max min [withscores]
:从大到小按分数排序。max和min表示分数范围。
zrevrank key member
:从大到小的顺序,求成员的排行。从0开始。
zscore key member
:返回成员的分数值。
zunionstore desKey numKeys key1 [key2 ...]
:求多个有序集合的并集。numKeys是有序集合的个数。
注意:对有序集合的操作时,需要注意区间表示的是值还是分数,支不支持"["。好在使用zset的频率并不高。
基数
基数是一种算法。用来计算需要多少内存空间来储存。基数并不是储存元素。而是某一个有重复元素的数据集合(一般是很大的数据集合)评估需要的空间单元数。
基本命令:
pfadd key element
:添加指定元素到HyperLogLog中。如果已经存储元素。则返回0,添加失败。
pfcount key
:返回基数值。
pfmerge desKey key1 [key2 ...]
:合并多个HyperLogLog,并将其保存在desKey。
在java中,增加一个元素到基数中用add方法,可以是一个或多个元素。求基数大小用size方法,合并基数用union方法,第一个参数是目标基数的key,然后可以是一到多个key。