Redis笔记
命令:
redis-server -v
info
String结构
set
get
help @string
mset
mget
incr
decr
strlen
setnx key value
set key value expire notexists/exists
ttl
点赞使用:incr + get
喜欢作者:incr + get
hash结构
Map<string,Map<string,string>>
hset Key key value
hget Key key
hlen
mset Key k1 v1 k2 v2
hgetall Key
hlen Key
购物车使用:hash
list结构
1:N 结构
微信公众号订阅列表
粉丝订阅列表
lpush 用户id 文章id1 文章id2
lrange 0 10
set结构
不可以重复
sadd key 1 11 1 2 3 4
srem key member
scard key (长度)
smembers
spop key 3
抽奖:
sadd
scard
spop key 2
srandmember key 3
点赞:
sadd msgId 用户id1 用户id2
srem msgId 用户id1
sismember
smember
微博社交关系
sadd s1 1 2 3 4 5
sdiff s2 3 4 5 6 7
sinter s1 s2
sunion
zset
今日热搜
排行榜
zadd key score member score2 member2
zrange key start end withscores
zincrby key score member
8大数据类型:
list、set、zset、hash、string、位图、hyperloglog统计、GEO地理
命令不区分大小写,key区分大小写
分布式锁
mysql
redis
zookeeper
都可以实现分布式锁
redis分布式锁
版本v1:
StringRedisTemplate.opsForValue().setIfAbsent(uuid,10l,TimeUnit.seconds);
try{
//超卖
}finally{
if(StringRedisTemplate.opsForValue().get(key).equals(uuid)){
StringRedisTemplate.opsForValue().delete(key)
}
}
版本v2:
解决判断是否删除自己的锁,和删除操作不是原子的。
解决办法:redis自身的事物或者lua脚本
事务命令:
multi、exec、discard、watch
StringRedisTemplate.opsForValue().setIfAbsent(uuid,10l,TimeUnit.seconds);
try{
//超卖
}finally{
while(true){
StringRedisTemplate.watch(key);
if(StringRedisTemplate.opsForValue().get(key).equals(uuid)){
StringRedisTemplate.enbaleTransationSupport(true);
StringRedisTemplate.opsForValue().delete(key)
List<Object> list = StringRedisTemplate.exec();
if(list == null){
continue;
}
StringRedisTemplate.unwatch
}
}
}
Jedis jedis = RedisUtils.getJedis();
String script = "if redis.call('get', KEYS[1]) == ARGV[1] "
+ "then "
+ " return redis.call('del', KEYS[1]) "
+ "else "
+ " return 0 "
+ "end";
try {
Object o = jedis.eval(script, Collections.singletonList(REDIS_LOCK),//
Collections.singletonList(value));
if("1".equals(o.toString())) {
System.out.println("---del redis lock ok.");
}else {
System.out.println("---del redis lock error.");
}
详细笔记:
https://blog.csdn.net/u011863024/article/details/114684428
https://blog.csdn.net/u011863024/article/details/115270840
redis是AP,异步复制导致锁丢失,一致性低,并发高,性能高。
zookeeper是CP,一致性好,性能低,并发低。
@Configuration
public class RedisConfig {
@Bean
public Redisson redisson() {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379").setDatabase(0);
return (Redisson)Redisson.create(config);
}
}
RLock redissonLock = redisson.getLock(REDIS_LOCK);
redissonLock.lock();
try {
//doSomething
}finally {
if(redissonLock.isLocked() && redissonLock.isHeldByCurrentThread()) {
redissonLock.unlock();
}
}
1)加了锁,业务逻辑出异常,会导致没有释放锁,需要放到finally块中。
2)宕机,会导致没有走finally块,需要加过期时间,自动解锁。
3)加锁和过期时间只能放在一起,保证原子性
4)判断是自己的锁,才能删自己的锁。
5) 删除使用lua脚本保证原子性或者使用事务保证原子性
如何配置和修改内存大小?
redis.conf
maxmemory (64位没限制内存大小,物理内存的大小,32位默认是3G),单位是字节
生产上如何配置?
设置为最大物理内存的0.75
config set maxmemory xxx
config get maxmemory
内存满了怎么办?
报oom
command not allowed when use memory》maxmemory
定期删除和惰性删除?
8种缓存淘汰策略
noeviction(直接报错,默认)
redis过期键的删除策略
如果一个键是过期的,那它到了过期时间之后是不是马上就从内存中被被删除呢?
答:不是
那过期后到底什么时候被删除呢??是个什么操作?
三种不同的删除策略
定时删除 - 立即删除。总结:对CPU不友好,用处理器性能换取存储空间(拿时间换空间)
惰性删除 - 下次访问再删除。总结:对memory不友好,用存储空间换取处理器性能(拿空间换时间)
上面两种方案都走极端 - 定期删除 - 定期抽样key,判断是否过期(存在漏网之鱼)
noeviction:不会驱逐任何key
volatile-lfu:对所有设置了过期时间的key使用LFU算法进行删除
volatile-Iru:对所有设置了过期时间的key使用LRU算法进行删除
volatile-random:对所有设置了过期时间的key随机删除
volatile-ttl:删除马上要过期的key
allkeys-lfu:对所有key使用LFU算法进行删除
allkeys-Iru:对所有key使用LRU算法进行删除
allkeys-random:对所有key随机删除
手写LRU算法?
浙公网安备 33010602011771号