1.啥是Redis
1.1 Reids全拼Remote Dictionary Server就是远程字典服务,是当下流行的NoSql技术,也同时被人们称为结构化数据库,所谓结构化就是可以支持五种数据结构;
1.1.1 String常用方法:添加(set)、查询(get)、追加(append)、获取长度(strlen)、判断是否存在(exsits)、数值自增(incr)、数值自减(decr)、截取(getrange)、替换(setrange)、设置过期(setex)、不存在设置(setnx)、mset操作:添加k-v形式的字符串(添加对象)、mget:根据k获取v(获取对象)
总结:
1.1.2 list常用方法:左插入(lpush)、右插入(rpush)、查看(lrange)、左移除(lpop)、右移除(rpop)、查询制定下表元素(lindex)、获取集合长度(llen)、根据value值删除指定值(lrem)、截取元素(ltrim)、移除指定集合中最后一个值到新的集合中(rpoplpush)、更新操作(lset)、插入操作(linsert)
总结:1.链表,before Node after,left,right都可以插入值
2.如果key不存在,重新创建链表
3.如果key存在,新增数据
4.如果移除了所有值,空链表,也代表不存在
5.两边插值效率快,中间插效率慢
6.消息排队,消息对联,栈
1.1.3 hash常用方法:添加hash(hset)、查询(hget)、查询所有(hgetall)、删除hash中指定的值(hdel)、获取hash的长度(hlen)、判断key是否存在(hexists)、获取所有的key(hkeys)、获取所有value值(hvals)、给值增加量(hincrby)、不存在添加(hsetnx)
总结:比String更适合存储对象
1.1.4 set常用方法:添加(sadd)、查看(smembers)、判断是否存在(sismember)、查看长度(scard),移除指定元素(srem)、抽取随机元素(srandmember)、删除随机元素(spop)、移动指定元素到新的集合(smove)、取差集(sdiff)、取交集(sinter)、取并集(sunion)
1.1.5 zset常用方法:添加(zadd)、查询(zrange)、排序(小 -》大)(zrangebyscore)、排序(大 - 》 小)(zrevrange)、查询所有值包含key(zrangebyscores withscores)、移除元素(zrem)、查看元素个数(zcard)、查询指定区间的元素个数(zcount)
3.三大特殊数据类型
3.1 Geospatial(地理位置):
3.2 HyperLogLog(基数):
3.3 BitMap(位存储):
4.Redis中的事务和乐观锁
4.1 事务
4.1.1 原子性:一个事务是不可能再分割的单位,要么全部成功,要么全部失败。
4.1.2 一致性:可以让数据从一种一致性状态转变为另一种一致性状态
4.1.3 隔离性:多个事务在执行期间互不干扰
4.1.4 持久性:事务一旦被提交,就会持久化到数据库中,提交的事务不可回滚
4.2 为啥使用乐观锁:保证在并发情况下操作Redis时数据的准确性,优点,在更新数据的时候会去监视被更新的数据有没有被其他线程所操作,如果没有就正常执行,有的话就执行失败。
4.3 悲观锁:什么时候都会出现问题,他是一直监视着,在当前线程没有执行完之前,其他线程就不能执行,十分浪费性能。
5.关于Jedis
5.1 redis推荐的java连接开发工具,使用方法与redis控制台使用方式完全一致。优点:在Java中对数据的操作更加简单。
6.封装RedisTemplate类
package com.biz.monitor.starter.controller;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
// 这是我给大家写好的一个固定模板,大家在企业中,拿去就可以直接使用!
// 自己定义了一个RedisTemplate
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
// 我们为了自己开发方便,一般直接使用 <String, Object>
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
// Json序列化配置
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// String 的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
7.RDB(快照模式)、AOF(追加模式)
7.1 RDB(快照模式):先将数据持久化到一个临时文件中,待所有持久化结束后,这个临时文件就会替换掉上次持久化好的文件,在这个过程中,主进程不进行任何IO操作这样做的性能就得到了保证,确保了极高的性能。
7.1.2 优点:适合大规模数据的回复、对数据完整性要求不高。
7.1.3 缺点:需要间隔进程操作,若redis宕机了,最后一次修改的数据就没有了、fork进程的时候,会占用一定的内容空间。
7.2 AOF(追加模式):AOF持久化方式记录了对服务器每次写的操作,每次的写操作都会追加到文件的末尾,当服务器重启时,会执行这些命令来恢复数据
7.2.1 优点:每一次的修改会同步,数据完整性更好、每秒都在同步,最多丢失两秒的数据、不同步,效率高
7.2.2 缺点:相对于数据文件来说,aof远远大于rdb,修复速度也比rdb慢、运行效率也别rdb慢
总结:
1.RDB持久化方式能在一定的时间间隔内对数据进行快照储存
2.AOF持久化方式是记录每一次对服务器的写操作,当服务器进行重启时,会执行文件中的命令来恢复数据,AOF是以追加的方式将写的操作记录到文件末尾,Redis还能对AOF文件进行后台重写,是AOF的文件不至于过大。
3.Reids只负责缓存,如果你的数据只需要在程序运行的时候存在,就可以不选择持久化方式。
4.同时开启两种持久化方式:
-
-
- 这种情况下,在Redis重启的时候会优先载入AOF文件来恢复原始数据
- RDB的数据不实时,同时使用两者时服务器也只会找AOF文件,但是不能只是用AOF,RDB更适合用于备份数据库(AOF在不断变化,不好备份),快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。
-
5.性能建议:
-
-
- 因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留 save 900 1 这条规则。
- 如果Enable AOF ,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了,代价一是带来了持续的IO,二是AOF rewrite 的最后将 rewrite 过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上,默认超过原大小100%大小重写可以改到适当的数值。
- 如果不Enable AOF ,仅靠 Master-Slave Repllcation 实现高可用性也可以,能省掉一大笔IO,也减少了rewrite时带来的系统波动。代价是如果Master/Slave 同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个 Master/Slave 中的 RDB文件,载入较新的那个,微博就是这种架构。
-