redis笔记
Redis笔记
1.常用的命令
set key 值 存储
get key 值 获取
select 数据库索引 切换到哪一个数据库
keys * 查看数据库中的所有数据信息
flushdb 清空当前库信息
flushall 清空所有库信息
exits key 判断是否存在
move key 1 移除当前属性
expire key 过期时间 设置属性的过期时间
ttl key 查看过期时间
type key 查看当前属性的类型
append key 需要添加的值 在字符串后面添加字符串 如果当前字符串不存在 就相当于 setkey
strlen key 查看当前属性长度
incr 自增1
decr 自减1
incr 属性名 步长 可以设置步长 指定增量
getrange key 0 3 截取字符串 [0,3]
getrange key 0 -1 获取全部的字符串信息 相当于get key
setrange key 1 xx 替换字符串 从位置1开始,然后替换
setex(set with expire ) 设置过期时间
setnx(set if not exit) 不存在再设置
mset key value key value 可以批量设置参数
mget key value key value 可以批量获取
msetnx 是一个原子性操作,要么一起成功,要么一起失败
2.对象
set user:1 {name:zhangsan,age:3} 设置一个user:1 对象,值为json字符串来保存一个对象
getset db redis 如果不存在值,则返回nil
getset db mongodb 如果存在值,获取原来的值,并设置新的值
3.list(列表)
lpush 将一个或多个元素插入到列表头部(左边)
lrange key 0 -1 查看列表的元素
rpush 将一个或多个元素插入到列表尾部(右边)
ltrim key 1 2 通过下标指定截取长度,这个list已经hmset被改变了,截断了只剩下截取的元素
lpoplpush 移除列表最后一个元素,将他移动到新的列表顶部
lset 将列表中指定下标的值替换为另外一个值,更新操作
linsert key before/after 在这个索引的前后 插入一个值
4.Set(集合)
sadd 添加数据
smembers 查看数据
smembers key 值 判断Set中是否有该元素
scard key 查看set集合中的元素个数
srem key 要移除的元素 删除
srandmember key 随机抽选一个元素
sdiff 取差集
sinter 取交集
sunion 取并集
5.Hash(哈希)
hset key k v set一个具体的 key和value
hget key k 获取值
hmset 设置多个key value
hmget 获取多个key value
hgetall myhash 获取所有key value
hdel key k v 删除hash指定key字段
6.Zset(有序集合)
zadd :增加
zrangebyscore 排序显示
zrangebyscore withscores
7.三种特殊的类型
geospatial 地理位置
geoadd 添加经纬度
geopos 获取经纬度
geodist 返回两个给定位置之间的距离
georadius 以给定的经纬度为中心,找出某一半径内的元素
georadiusbymember 找出位于指定范围内的元素 中心点是由给定的位置元素决定
geohash 将二维的经纬度转换为一维的字符串
PFadd key element 可以添加多个元素
PFCOUNT key 可以统计元素的个数
PFMERGE 合并成功后指定的key key1 key2 合并去重复
8.Bitmap(位存储)
setbit 设置存储
getbit 获取存储
bitcount 统计
9.redis的事务
开启事务(multi)
命令入队()
执行事务(exec)
10.discard 取消事务
编译时异常的话,就全部都不执行成功
运行时异常的话,不保证原子性,就会有的成功,有的失败
11.乐观锁
watch 需要监视的
12.什么是RDB?
在进行 RDB 的时候,redis 的主线程是不会做 io 操作的,主线程会 fork 一个子线程来完成该操作;
Redis 调用forks。同时拥有父进程和子进程
子进程将数据集写入到一个临时 RDB 文件中。
当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
这种工作方式使得 Redis 可以从写时复制(copy-on-write)机制中获益(因为是使用子进程进行写操作,而父进
程依然可以接收来自客户端的请求。)
13.RDB触发机制
1.save的规则满足的情况下,会自动触发rdb原则
2.执行flushall 命令也会触发rbd规则
3.退出redis,也会自动产生rdb文件
14.什么是AOF?
1. 快照功能(RDB)并不是非常耐久(durable): 如果 Redis 因为某些原因而造成故障停机,那么服务器将丢失
最近写入、以及未保存到快照中的那些数据。 从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化。
如果要使用AOF,需要修改配置文件:
appendonly no:默认是no,默认使用的是RDB,yes表示使用aof
2.aof保存的文件名称
3.如果这个aof文件有错位,这时候redis是启动不起来的,我需要修改这个aof文件
redis给我们提供了一个工具redis-check-aof --fix
优点:
每一次修改都会同步,文件的完整性会更加好
没秒同步一次,可能会丢失一秒的数据
从不同步,效率最高
缺点:
相对于数据文件来说,aof远远大于rdb,修复速度比rdb慢!
Aof运行效率也要比rdb慢,所以我们redis默认的配置就是rdb持久化
14.Redis发布与订阅
14.1 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
常用的命令
PSUBSCRIBE pattern [pattern..] 订阅一个或多个符合给定模式的频道。
PUNSUBSCRIBE pattern [pattern..] 退订一个或多个符合给定模式的频道。
PUBSUB subcommand [argument[argument]] 查看订阅与发布系统状态。
PUBLISH channel message 向指定频道发布消息
SUBSCRIBE channel [channel..] 订阅给定的一个或多个频道。
SUBSCRIBE channel [channel..] 退订一个或多个频道
14.2 使用java代码
首先是发布者,这里开启了定时任务
然后是订阅者,会收到消息
这里就是配置类的相关操作
14.Redis主从复制
概念
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(Master/Leader),后者称为从节点(Slave/Follower), 数据的复制是单向的!只能由主节点复制到从节点(主节点以写为主、从节点以读为主)。
作用
数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余的方式。
故障恢复:当主节点故障时,从节点可以暂时替代主节点提供服务,是一种服务冗余的方式
负载均衡:在主从复制的基础上,配合读写分离,由主节点进行写操作,从节点进行读操作,分担服务器的负载;
尤其是在多读少写的场景下,通过多个从节点分担负载,提高并发量。
高可用基石:主从复制还是哨兵和集群能够实施的基础。
环境配置
查看当前库的信息:info replication
既然需要启动多个服务,就需要多个配置文件。每个配置文件对应修改以下信息:
端口号
pid文件名
日志文件名
rdb文件名.
主机处理写请求,从机只能读
15. 哨兵模式(自动选取老大的模式)
主从切换技术的方法是:当主服务器宕机后,需要手动把一台服务器切换为主服务器,这就需要人工干预,费时费力,还会造成一段时间内服务器不可用。这不是一种推荐方式,更多时候,我们优先考虑哨兵模式,Redis从2.8开始正式提供了Sentinel(哨兵)架构来解决这个问题。
谋朝篡位的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将库转换为主库。
哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例
哨兵的作用
1.通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器
2.当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让他们切换主机
然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。
小结
通俗来讲哨兵就是,比如多个哨兵互相监视,并且监视主机,当一个哨兵发现主机挂了,就会认为主机主管下线,如果哨兵二和三
也发现了主机挂了,也会记录为主观下线,然后进行投票,当他们都认为主机挂了,那么哨兵就会从接下来的两个
从机中投票选取一个从机作为主机
优点:
哨兵模式,基于主从复制模式,所有主从配置的优点它都有
主从可以切换,故障可以转移,系统的可用性就会更好
哨兵模式就是主从模式的升级,手动到自动,更加健壮
缺点:
Redis不好在线扩容,集群容量一旦达到上限,在线扩容就十分麻烦
实现哨兵模式的配置是非常麻烦的,里面有很多选择
附:java连接redis
1.工具类的封装代码
@Configuration
public class RedisConfig {
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter)
{
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
//订阅了一个叫chat的通道
container.addMessageListener(listenerAdapter, new PatternTopic("wy"));
return container;
}
@Bean
MessageListenerAdapter listenerAdapter(fish receiver) {
//给messageListenerAdapter 传入一个消息接受的处理器,利用反射的方法调用“receiveMessage”
//不填defaultListenerMethod默认调用handleMessage
return new MessageListenerAdapter(receiver, "getMessage");
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) throws UnknownHostException {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
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);
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;
}
}
2.配置类代码
@Configuration
public class RedisConfig {
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter)
{
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
//订阅了一个叫chat的通道
container.addMessageListener(listenerAdapter, new PatternTopic("wy"));
return container;
}
@Bean
MessageListenerAdapter listenerAdapter(fish receiver) {
//给messageListenerAdapter 传入一个消息接受的处理器,利用反射的方法调用“receiveMessage”
//不填defaultListenerMethod默认调用handleMessage
return new MessageListenerAdapter(receiver, "getMessage");
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) throws UnknownHostException {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
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);
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;
}
}