赞
踩
高并发下查询一个值,缓存中没有,数据库中也没有,布隆过滤器
解决方案:
缓存中大量数据同时到期,高并发下,所有请求都走向数据库
解决方案:
尽量不要把所有缓存都设置在同一时间过期, 通过加锁或者队列只允许一个线程查询数据库和写缓存, 其他线程等待.
通过加锁或者队列只允许一个线程查询数据库和写缓存,其他线程等待。
双重检测锁解决热点缓存问题,需要加volatile防止指令重排
高并发下,一个热点缓存到期,然后去数据库中去取,当还没有放入缓存中时,大量请求过来
解决方案:
Integer count = redis.get("key");if (count == null) { synchronized { count = redis.get("key"); if (count == null) { count = repo.getCount(); redis.put("key", count); } }}
if (redis.setnx(lockKey, requestId, NX, PX) == 1) {}
解决方案:
延时双删策略, 先更新数据库,再删缓存
public void write(String key,Object data){ redis.delKey(key); db.updateData(data); // 可以将以下两步作为异步处理 Thread.sleep(1000); redis.delKey(key);}
Redis是一种用C语言开发的,高性能的,键值对key-value形式的noSql数据库
支持5种string, hash, set, list, 有序集合类型(sorted set, 简称zset)等数据类型
劣势就是存储的数据缺少结构化
应用场景:
redis使用multi, exec, discard, watch, unwatch实现事务
redis不支持事务回滚
执行multi后,Redis会将命令逐个放入队列中,然后用exce执行这个队列中的命令
而watch是在multi之前,watch某个属性,表示我这个multi块中可能要修改该属性,如果multi块中的命令在未执行前有客户端修改了该请求,那么该multi块中的命令就会执行失败。
redis持久化的方式有两种,RDB和AOF
rdb是使用快照(snapshotting)的方式进行持久化的
触发快照的时机
redis获取所有数据库:
config get databases(默认有16个数据库,index从0开始)
select 0选择数据库
快照规则(或的关系)
save 900 1 “**15分钟内有1次修改就进行快照”**
save 300 10 “**5分钟内有10次修改就进行快照”**
save 60 10000 “**1分钟内有10000次修改就进行快照”**
dir ./ 指定快照地址(rdb文件地址)
dbfilename dump.rdb
快照过程
优缺点
AOF: 每执行一条更改,Redis就会将该命令写入AOF文件. 实际上是先写入到硬盘缓存,然后通过硬盘缓存刷新机制保存到文件。
appendfsync always
appendfsync everysec(默认)
appendfsync no(由系统进行sync)
默认关闭,打开是appendonly yes
在数据量比较大的时候,频繁的写入和修改,aof文件会变得非常臃肿,所以我们可以设置重写规则:
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
定时生成RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快。
Redis 支持同时开启 RDB 和 AOF,系统重启后,Redis 会优先使用 AOF 来恢复数据,这样丢失的数据会最少。
如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久。
AOF 将 Redis 执行的每一条命令追加到磁盘中,处理巨大的写入会降低 Redis 的性能,不知道你是否可以接受。
原理:
分为全量同步和增量同步
Redis cluster不支持mget操作. 最初是facebook, 2010年使用memcache作缓存, 共有3000个节点. 发现节点太多, 连接频率下降. 继续增加节点, 并没有改善, 是因为IO的成本已经超过数据传输.
所以redis cluster也因此不支持mget操作.redis引入cluster模式后, 是将数据hash到16384个slot上, 每个node负责一部分slot.
mget优化方案:
Martin和Redis作者antirez之间的争辩:
martin挑了两个缺点:
1. 对于提升效率的场景, redlock太重
2. 对于正确性要求极高的场景, redlock并不能保证正确性;
问题: 在client1获取锁之后, 由于某种原因发生系统停顿, 锁过期, 然后client1执行操作; client2这时候也会拿到锁, 就会出现问题)
问题: A, B, C, D, E 5个redis节点,如果C的时间走得快, client1拿到锁(A, B, C), C节点先过期, client2又拿到了(C, D, E)这样就出问题了;
所以Redis从根本上来说是AP, 而分布式锁是要求CP的.
背景: 因业务原因, 需要大量存储key-value数据, key和value都为string, 如果存储1千万条数据,占用了redis共计1.17G的内存. 当数据量变成1个亿时,实测大约占用8个G. 但是修改为key(int), value 为ziplist时, 内存占用为123M, 减少了85%.
步骤:
redis命令执行过程
蓝色的表示可能发生高延迟的地方
redis提供的慢查询统计功能: slowlog get {n}, 默认返回执行超过10ms(可配置)的命令.
slowlog get会返回值如下:
> slowlog get1) (integer) 26 # 在慢日志中的序列号2) (integer) 1450253133 # 该记录执行的系统时间3) (integer) 43097 # 该记录执行所消耗的时间4) "flushdb" # 执行的操作
redis高延迟原因
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。