# redis的那些事

redis的那些事

redis的那些事

MemCache、Redis、MongoDB被称为NoSQL三剑客

##NoSQL数据库(Redis)

数据存储位置 内存
数据结构 没有预定义的模式
数据操作方式 所有数据都是键值对,没有声明性查询语言
事务控制 基于乐观锁的松散事务控制
NoSQL数据库的最大优势体现为:高性能、高可用性和可伸缩性。

1)官网地址
https://redis.io
2)下载地址
https://redis.io/download
3)命令参考地址
http://redisdoc.com

## 应用场景

###1)缓存
使用Redis可以建立性能非常出色的缓存服务器,查询请求先在Redis中查找所需要的数据,如果能够查询到(命中)则直接返回,大大减轻关系型数据库的压力。
###2)数据临时存储位置
使用token(令牌)作为用户登录系统时的身份标识,这个token就可以在Redis中临时存储。
###3)分布式环境下解决Session不一致问题时的Session库
Spring提供了一种技术解决分布式环境下Session不一致问题,叫SpringSession。而Redis就可以为SpringSession提供一个数据存储空间。
###4)流式数据去重
在Redis中有一种数据类型是Set,和Java中的Set集合很像,不允许存储重复数据。借助这个特性我们可以在Redis中使用Set类型存储流式数据达到去重的目的。

## 五种常用数据类型
string 它是key对应的一个单一值 可以包含任何数据,比如jpg图片或者序列化的对象,Redis中一个字符串值的最大容量是512M
list 字符串列表,按照插入顺序排序,底层是基于链表实现,头尾效率高,中间效率低
set String类型的无序集合,基于哈希表实现的
hash 本身就是一个键值对集合。可以当做Java中的Map<String,String>
zset 和set一样,但每个元素都会关联一个double类型的分数,通过分数来为集合中的成员进行从小到大的排序实现有序不重复,分数(score)可以重复

默认有16个数据库
select + 数据库编号 切换数据库
dbsize 查看数据库长度(存储了多少个key)
keys ? 查看只有一位的key keys * 查看所有key
type key名 查看key对应的值的类型
move key名 db库名 把一组键值对移动到指定库
del key名 [可以填写多个key名] 删除key
exists key名 [可以填写多个key名] 查看key是否存在,可以查看多个,存在返回的是存在的数量,不存在返回0
randomkey 在现有的key中随机返回一个
rename key名 新key名 改变key名,新key名可以是已有的
renamenx 改变key名新key名不能是已有的
ttl key名 查看key可以存在多久,-1表示永久
expire key名 时间(秒) 设置key在多少秒后过期被删除
persist key名 移除过期时间改为永久

## sting类型操作
set key名 value值 [存活秒数] [存活毫秒数] [nx,key不存在时执行/xx,key存在时执行]
给key设置一个sting类型的值,可以创建不存在的key,[]的内容可以不要
get key名 得到string类型的key对应的值,无法操作其他类型的key
strlen key名 返回key的值的字符串长度
append key名 value值 将value值追加进key的值后,返回追加后的字符串长度
incr key名 自增1,只能对数字类型的key操作,可以创建value为1的key
decr key名 自减1,只能对数字类型的key操作,可以创建value为-1的key
incrby key名 数字 增加指定数字值,只能对数字类型的key使用,可以创建value为指定数字的key
decrby key名 数字 减少指定数字值,只能对数字类型的key使用,可以创建value为-指定数字的key
getrange key名 起始下标 结束下标 查看key中指定范围的值
setrange key名 下标位置 value值 在指定下标位置使用指定值进行替换
setex key名 秒数 value值 设置key,value存活的指定秒数 时间结束会删除整个key
setnx key名 value值 设置还未存在的key,value key不可以存在,value不影响
mset key value key value … 一次设置多个key-value,已存在的会被覆盖
mget key key key … 可以一次返回多个key对应的value值,不存在的key返回nil
msetnx key value key value … 一次设置多个key-value,只能设置不存在的,有一个已存在的key都不会成功
getset key value 更改key对应的value值,返回原来的value值

## list类型操作
lpush key value value … 从左到右向key中放入多个value,可以创建/改变key
lrange key 0 -1 查看key的value
llen key 查看key的长度即value的个数
lpop key 从左弹出第一个value 弹出指查看并删除
rpoplpush key key 从第一个key中弹出左边第一个value并从左到右写入第二个key中,第二个key可以是不存在的key
lindex key 下标 根据key的索引值查看value
linsert key before/after value1 value 在key中value1值左/右插入value
lpushx key value value … 在已存在的key中从左到右添加value
lrem key 数量 value 删除key中指定数量的value
lset key 下表 value 使用value替换key中指定下标的值
ltrim key 下标1 下标2 保留两个下标之间的数据,删除其他的

## set类型操作
sadd key value value … 向key中放入value,可以创建key,会自动去除重复的value
smembers key 查看key的值
scard key 返回key的长度
sismember key value 查看key中是否有指定的value值,有返回1,没有返回0
srem key value value … 删除key中value值,返回删除成功的数量
sinter key key … 查看多个key的交集
sinterstore key1 key key … 将多个key的交集放入key1
sdiff key key … 查看多个key的差集
sdiffstore key1 key key … 将多个key的差集放入key1
sunion key key key … 查看多个key的并集
sunionstore key1 key key … 将多个key的并集放入key1
smove key1 key value 将key1 的value值放入key
srandmember key [数量] 随机返回key中指定数量的value 不填默认1个
spop key [数量] 随机弹出key中指定数量的value 不填默认1个

hash类型操作 一个hash有多个key,一个key有多个field场地,一个场地有一个value
hset key field value field value … 向key中的指定场地放入value,可以用来创建hash,可以一次创建多个,会替换已存在的
hgetall key 查看key中全部的场地值和value值
hget key field 查看key中指定场地对应的value值
hlen key 查看key的长度即key中的field数量
hkeys key 查看key中的所有field场地
hvals key 查看key中的所有value值
hexists key field 判断key中是否存在指定的field值,存在返回1,不存在返回0
hdel key field 删除key中指定的field值,成功返回1,不成功返回0
hincrby key field 数值 使指定field中的数值类型的value增加指定数值,做加法运算
hmget key field field … 查看指定key中多个场地对应的value值
hmset key field value field value … 和hset暂未发现有不一样的,都能操作多个,都会覆盖已存在的
hsetnx key field value 在场地不存在时添加
redis持久化机制
RDB,以快照的形式将数据保存在磁盘中,默认开启
触发时机:
默认情况:
900s(15min)内有一次key操作
300s(5min)内有十次key操作
60s(1min)内有10000次操作
使用保存命令时
save 阻塞当前进程来将数据落盘
bgsave 在后台开启一个进程将数据落盘
使用flushall命令
清空数据库时也会触发RDB,生成dump.rdb文件,但内容是空的没有意义
关闭服务器
使用shutdown命令正常退出时,也会执行一次RDB
配置设置
save “” 禁用RDB
dbfilename dump.rdb 数据存储文件的文件名
dir redis工作目录路径 指定存放存储文件的目录路径,必须是目录
优势
速度快,适合大哥规模的数据恢复
劣势
宕机会丢失最后一次快照后的所有修改,不能保证数据的绝对一致性和完整性

AOF保存的是生成数据的命令行操作,AOF默认是关闭的,开启后根据配置文件设置触发时机
配置设置
	appendonly   		yes/no                   是否开启AOF 		
	appendfilename 		"文件名"		             AOF文件的文件名  
	dir   				redis工作目录路径         指定存放持久化文件的目录的路径,必须是目录
	appendfsync			always					 每次数据修改都会保存,效率最低,安全度最高	
						everysec				 每秒执行一次写入,折中	
						no						 由操作系统自己决定时间,最快
AOF重写	将多组命令行转化为相同结果的一组命令行 类似于 1+1+1 写为 1*3 节省了占用空间
重写触发时机
	auto-aof-rewrite-percentage 100 			 文件体积增大为原来的100%后重写
	auto-aof-rewrite-min-size 64mb 				 文件大小达到64M时重写	
重写会占用内存进行操作,实际使用中尽量少触发	
优势
	appendfsync always 在理论上可以保证数据绝对的一致性和完整性(但会影响性能)
劣势
	持久化同样的数据,文件要比RDB大,读取速度比RDB慢,同步写时效率比RDB低

RDB和AOF同时开启
	二者同时使用时,redis启动时会优先读取AOF的数据来恢复原始数据,因为理论上AOF比RDB完整度要高
	但不建议只使用AOF,备份数据库,快速启动时使用	RDB更合适

持久化文件修复
radis启动时读取的持久化文件有问题时会启动失败
修复命令
备份要修复的appendonly.aof文件 (以aof文件为例,RDB文件同理)
bin/redis-check-aof --fix ./appendonly.aof
重启redis
修复实际是删除损坏部分,不能找回损坏的部分,相当于胳膊不会动直接去掉胳膊,不能修好胳膊

持久化设置建议
如果Redis仅仅作为缓存可以不使用任何持久化方式
其他应用方式综合考虑性能和完整性、一致性要求
RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则
AOF重写的基础大小默认值64M太小了,可以设到5G以上。默认超过原大小100%大小时重写可以改到适当的数值
如果不开启AOF,仅靠Master-Slave Replication 实现高可用性能也不错。

事务控制的命令
MULTI 启动一个队列
往队列中放入要执行的命令
EXEC 执行队列
DISCARD 放弃队列
WATCH 观察key,有队列外的命令操作key时,放弃当前队列(乐观锁)
UNWATCH 放弃观察

对列中命令失败的两种情况
	编译错误,格式存在问题,会直接报错
		multi
		set a 1
		incr a 
		incr a w
		 ERR wrong number of arguments for 'incr' command
	执行中报错,格式没问题,但使用了超过预期的数据
	 执行:	
		multi
		set a 1
		incrby a 2
		incrby a w
		incrby a 3
		EXEC
	 结果:
	 	3
		ERR value is not an integer or out of range
		6
要么在队列编写时就能看出来问题没必要回滚,要么结果已经出来了无法回滚,基于这两种情况,redis不支持回滚

乐观锁和悲观锁
悲观锁:执行操作前把数据锁定,操作完成后释放锁,其他操作才可以继续操作。
乐观锁:执行操作前不锁定数据,碰撞发生了就放弃自己的操作。

读写分离的好处
性能优化,减少服务器压力,强化数据安全,避免单点故障

哨兵模式
redis启动多个sentinel(哨兵)对服务器进行监控
主观下线:1个哨兵监控一台服务器时,检测到服务器下线(哨兵会有一个补刀的机制)
客观下线:多个哨兵监控一台服务器时,超过半数的哨兵检测到服务器下线(常使用半数原则,可以在配置文件中修改这个数量)
客观下线更稳定,避免了某个哨兵服务出现问题发生’谎报军情’的情况

jedis的创建
将Redis配置文件中bind配置项设置为本机IP
bind [你的实际IP]
bind 192.168.9.102
导入依赖

redis.clients
jedis
2.9.0

编写代码
//指定Redis服务器的IP地址和端口号
Jedis jedis = new Jedis(“192.168.9.102”, 6379);

//执行ping命令
String ping = jedis.ping();

System.out.println(ping);

//关闭连接
jedis.close();

JedisPool的创建
//声明Linux服务器IP地址
String host = “192.168.9.102”;

//声明Redis端口号
int port = Protocol.DEFAULT_PORT;

//创建连接池对象
JedisPool jedisPool = new JedisPool(host, port);

//获取Jedis对象连接Redis
Jedis jedis = jedisPool.getResource();

//执行具体操作
String ping = jedis.ping();

System.out.println(ping);

//关闭连接
jedisPool.close();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值