48、redis
< 返回列表时间: 2019-07-04来源:OSCHINA
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
redis
概念:redis是一款高性能的NOSQL系列的非关系型数据库
应用场景:
缓存(数据查询,短连接,新闻内容,商品内容)
聊天室的在线好友列表
任务队列(秒杀,抢购,12306等)
应用排行榜
网址访问统计
数据过期处理
分布式集群架构中的session分离

全局key操作:
flushdb :清空当前选择的数据库
del mykey :删除key
move mysetkey 1 :将当前数据库中的mysetkey键移入到id为1的数据库中
rename mykey mykey1 :将mykey改名为mykey1
renamex oldkey newkey:如果newkey已经存在,则无效
expire mykey 100:将该键的超时设置为100秒
persist mykey:将该key的超时去掉,变成持久化的键
keys my* :获取当前数据库中所有以my开头的key
exists mykey :若存在返回0,不存在返回1
select 0:打开id为0的数据库
ttl mykey:查看还有多少秒过期,-1表示永不过期,-2表示已经过期
type mykey:返回mykey对应的值的类型

命令操作:
1、redis的数据结构
redis存储的是:key-value格式的数据,其中key都是字符串,value有5种不同的数据结构
value的数据结构:1、字符串类型:String
2、哈希类型:hash:map格式
3、列表类型:list:LinkedList格式
4、集合类型:set
5、有序集合类型:sortedset
2、字符串类型:String ,redis最基本的类型,一个key对应一个value,String类型是二进制安全的,意思是String可以包含任何数据,比如jpg图片,或者序列化的对象,一个键最大能存储512MB
存储:set key value
获取:get key
删除:del key
例如:
set mykey “test” :为键设置新值,并覆盖原有值
getset mycounter 0 :设置值,取值同时进行
setex mykey 10 “hello” :设置指定key的过期时间为10秒,在存活时间可以获取value
setnx mykey “hello” :若该键不存在,则为键设置新值,如果key已经存在则插入无效
mset key3 “stephen” key4 “liu”:批量设置键
del mykey:删除已有键
append mykey “hello” :若该键并不存在,返回当前value的长度,该键已经存在,返回追加后的value的长度
incr mykey:值增加1.若该key不存在,创建key,初始值设为0,增加后结果为1
decrby mykey 5 :值减少5
setrange mykey 20 dd:把第21和22个字节替换为dd,超过value长度,自动补0
exists mykey:判断该键是否存在,存在返回1,否则返回0
get mykey:获取key对应的value
strlen mykey:获取指定key的字符长度
ttl mykey :查看指定key的剩余存活时间
getrange mykey 1 20 :获取第2到第20个字节,若20超过value长度,则截取第2个和后面所有的
mget key3 key4 :批量获取键

3、哈希类型 :hash,可以看成具有<key,<key,value>>,其中同一个key可以有多个不同的值,所以该类型非常适合于存储值对象信息
存储:hset key field value
获取:hget key field,获取指定的field对应的值
hgetall key:获取所有的field和vlaue
删除:hdel key field
例如:
hset key field1 “s”:若字段field1不存在,创建该键及其与其关联的Hash,Hash中key为field1,并设value为s,若字段field存在,则覆盖
hsetnx key field1 “s” :若字段field1不存在,创建该键及与其关联的hash,hash中,key为field1,并设value为s,若字段存在,则无效
hmset key field1 “hello” field2 “world” :一次性设置多个字段
hdel key field1 :删除key键中字段名为field1的字段
del key:删除键
hincrby key field 1 :给field的值加1
hget key field1 :获取键值为key ,字段为field的值
hlen key :获取key键的字段数量
hexists key field:判断key键中是否存在字段名field1的字段
hmget key field1 field2 field3 :一次性获取多个字段
hgetall key :返回key键的所有field值及value值
hkeys key :获取key键中所有字段的field值
hvals key :获取key键中所有字段的value值

4、列表类型:list,按照插入顺序排序的字符串链表
存储:lpush key value:将元素加入列表的左边
rpush key value :将元素加入列表的右边
获取:lrange key start end:范围获取
删除:lpop key:删除列表最左边的元素,并将元素返回
rpop key:删除列表最右边的元素,并将元素返回
例如:
lpush mykey a b :若key不存在,创建该键及其关联的List,依次插入a,b 若List类型的key存在,则插入value中
lpushx mykey e:若key不存在,则此命令无效,若key存在,则插入value中
linsert mykey before a a1 :在a的前面插入新元素
linsert mykey after a a1 :在a的后面插入新元素
rpush mykey a b:在链表的尾部先插入b在插入a
rpushx mykey e :若key存在,在尾部插入e,若不存在,则无效
del mykey :删除已有键
lrem mykey 2 a :从头部开始找,按先后顺序,值为a的元素,删除数量为2个,若存在第3个,则不删除
ltrim mykey 0 2:从头开始,索引为0,1,2的3个元素,其余全部删除
lset mykey 1 e :从头开始,将索引为1的元素值,设置为新值e,若索引越界,则返回错误信息
rpoplpush mykey mykey :将mykey中的尾部元素移到头部
lrange mykey 0 -1 :取链表中的全部元素,其中0表示第一个元素,-1表示最后一个元素
lrange mykey 0 2 :从头开始,取索引为0,1,2的元素
lpop mykey :获取头部元素,并且弹出头部元素,出栈
lindex mykey 6 :从头开始,获取索引为6的元素,若下标越界,则返回nil

5、集合类型 :set 不允许重复元素,如果多次添加相同元素,set中仅保留该元素的一份拷贝
存储:sadd key value
获取:smembers key:获取set集合中的所有元素
删除:srem key value:删除set集合中的某个元素
例如:
asdd myset a b c:若key不存在,创建该键及与其关联的set,依次插入a,b,c,若key存在,则插入value中,插入不存在的元素
spop myset :尾部的b被移出,事实上b并不是之前插入的第一个或最后一个成员
srem myset a d f:若f不存在,移除a,d并返回2
smove myset myset2 a:将a从myset移到myset2
sismember myset a :判断a是否存在,返回值1表示存在
smembers myset 查看set中的内容
scard myset :获取set集合中元素的数量
srandmember myset:随机的返回某一成员
sdiff myset myset2 :显示myset和myset2比较后myset1独有的值
sdiff myset myset2 myset3:显示myset和myset2,myset3比较后myset独有的值
sdiffstore diffkey myset myset2 myset3 :3个集的和比较,独有的元素存入diffkey关联的set中
sinter myset myset2 myset3 :获得3个集合中都有的元素
sinterstroe interkey myset myset2 myset3 :把交集存入interkey关联的set中
sunion myset myset2 myset3 :获取3个集合中的成员的并集
sunionstore unionkey myset myset2 myset3 :把并集存入unionkey关联的set中

6、有序集合类型:sortedset:不允许重复元素,且元素有顺序,每一个成员都会有一个分数与之关联,通过分数来为集合中的成员进行从小到大的排序。成员是唯一的,但是分数却是可以重复的
存储:zadd key score value
获取:zrange key start end
删除:zrem key value
例如:
zadd myzset 2 “two” 3 “three” :添加两个分数分别是2和3的两个成员
arem myzset one two :删除多个成员变量,返回删除的数量
zincrby myzset 2 one :将成员one 的分数增加2,并返回该成员更新后的分数
zrange myzset 0 -1 WITHCSORES :返回所有成员和分数,不加WITHSCORES,只返回成员
zrank myzset one :获取成员one在sorted-set中的位置的索引值。0表示第一个位置
zcard myzset:获取myzset键中成员的数量
zcount myzset 1 2 :获取分数在1-2之间的成员数量
zscore myzset three :获取成员three的分数
zraangebyscore myzset (1 2 :获取分数大于1,小于等于2 的成员
zrangebyscore myzset -inf +inf limit 2 3 :返回索引是2和3的成员
zremrangebyscore myzset 1 2 :删除分数1-2的成员,并返回实际删除的数量
zremrangebyrank myzset 0 1 :删除位置索引0-1的成员
zrevrange myzset 0 -1 WITHSCORE :按位置索引从高到低,获取所有成员和分数
zrevrange myzset 1 3 :获取位置索引为1,2,3的成员
zrevrangebyscore myzset 3 0 :获取分数0-3之间的成员并且以相反的顺序输出
zrevrangebyscore myzset 4 10 limit 1 2 :获取索引是1 和2 的成员,并反转位置索引


持久化:redis是一个内存数据库,当redis服务器重启或者电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘的文件中
机制:RDB:默认方式,不需要进行配置,默认使用的机制,在一定的间隔时间中,检测key的变化情况,然后持久化数据
AOF:日志记录的方式,可以记录每一条命令的操作,可以每一次命令操作后持久化数据
注意:redis的持久化是可以禁用的,两种方式的持久化是可以同时存在的,但是当redis重启时,AOF文件会被优先用于重构数据

RDB详解:
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里,Redis会单独创建fork一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久华过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了如果需要进行大规模数据的恢复时还能有极高性能
默认情况下,redis会把快照文件存储为当前目录下一个名为dump.rdb的文件,要修改文件的存储路径和名称,可以通过修改配置文件redis.conf实现。
保存点可以设置多个,Redis的配置文件就默认设置了3个保存点
如果想禁用快照保存的功能,可以通过注释掉所有save配置到达,或者添加配置 save “”
启动快照的方式:
1、在配置文件中配置保存点
2、SAVE命令:SAVE命令会使用同步的方式生成RDB快照文件,这意味着在这个过程中会阻塞所有其他客户端的请求,因此不建议在生产环境使用这个命令
3、BGSAVE:BGSAVE命令使用后台的方式保存RDB文件,调用此命令后,会立刻返回OK返回码。redis会产生一个子进程进行处理并立刻恢复对客户端的服务。在客户端我们可以使用LASTSAVE命令查看操作是否成功
4、flushall:会产生一个dump.rdb文件,但里面是空的,无意义
注意:配置文件里禁用了快照生成功能,不影响SAVE和BGSAVE命令的效果

AOF详解:
以日志文件的形式来记录每个写操作,将rediscover执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据恢复到工作
启动:在redis.conf中修改默认的appendonly no 改为yes
同步策略:
1、appendfsync always:每修改同步,同步持久华,每次发生数据变更立即记录到磁盘,性能较差,但数据完整性比较好
2、appendsync everysec:每秒同步,异步操作,每秒记录,如果发生灾难,可能会丢失1秒数据
3、appendsync no:不同步
官方建议配置:每秒同步
AOF重写:AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阀值时,redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。
AOF文件持续增长而过大时,会fork出一条新进程来将文件重写,遍历新进程的内存中数据,每条记录有一条set语句,重写AOF文件的操作,并没有读取旧的AOF文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的AOF文件,这点和快照有点类似
Redis会记录上次重写时点AOF大小,默认配置上当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发,实际生产环境至少要2G

RDB优缺点
优点:
1、比起AOF,在数据量较大的情况下,RDB的启动速度更快
2、RDB文件是一个很简洁的单文件,它保存了某个时间点点redis数据,很适合用于备份
3、RDB很适合用于灾备。单文件很方便就能传输到远程服务器上
4、RDB的性能很好,需要进行持久化时,主进程会fork一个子进程出来,然后把持久化的工作交给子进程,自己不会有相关的I/O操作
缺点:
1、RDB容易造成数据丢失,假设每5分钟保存一次快照,如果redis因为某种原因不能正常工作,那么从上次产生快照到redis出现问题这段时间的数据就会丢失
2、RDB使用fork产生子进程进行数据的持久化,如果数据比较大的话可能会花费点时间,造成redis停止服务几毫秒

AOF优缺点
优点:
1、该机制带来更高的数据安全性,即数据持久性,redis中提供了3种同步策略
2、AOF日志文件是一个纯追加的文件,就算服务器突然Crash,也不会出现日志的定位或者损坏问题,甚至如果因为某些原因命令只写到一半到日志文件里,我们也可以用redis-check-aof这个工具很简单的进行修复
3、当AOF文件太大时,redis会自动在后台进行重写,重写很安全,因为重新是在一个新文件上进行,同时热地说会继续往旧文件追加数据
缺点:
1、在相同的数据集下,AOF文件的大小一般会比RDB大
2、在某些同步策略下,AOF的速度会比RDB慢

关于RDB和AOF的建议
1、官方建议同时开启两种持久化策略,因为有时需要RDB快照时进行数据库备份,更快重启以及发生AOF引擎错误的解决办法
2、因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了
3、如果选择AOF,只要硬盘许可,将两减少AOF rewrite的频率,因为一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成是阻塞几乎是不可避免的,可以设置到5G以上

Redis的事务
Redis通过MULTI,EXEC,DSCARD和WATCH四个命令来实现事务功能
MULTI:标记一个事务块的开始
EXEC:执行所有事务块内的命令
DISCARD:取消事务,放弃执行事务块内的所有命令
WATCH key:监视一个或多个key,如果在事务执行之前key被其他命令所改动,那么事务将被打断
注意:当遇到错误时,redis放过这种错误,保证事务执行完成,需要自己保重逻辑符合预期
Jedis:
概念:java操作redis数据库的工具
使用步骤:
1、导入jedis的jar包
2、使用

操作value数据类型:
1、字符串类型 :set:设置key-value
get:获得value
setex:设置指定时间过期的key-value
2、哈希类型:hset :设置
hget:获取
hgetall:获取全部
3、列表类型:lpush/rpush:存储
lpop/rpop:删除
lrange:获取
4、集合类型:sadd:存储
smembers:获取
5、有序集合类型:zadd:存储
zrange :获取

Jedis连接池:JedisPool
使用:
1、创建连接池对象,JedisPool
2、调用方法,getResource()方法获取Jedis连接


热门排行