简述
C语言编写,多路I/O复用模型(多个套接字、单个线程),非阻塞IO
6.0只是io多线程,work还是单线程的
Disque重用了大量 Redis 的底层代码,可以作为队列消息队列使用
架构图
redis底层架构安装
https://www.cnblogs.com/zongfa/p/7808807.html
ubuntu 安装(无依赖):
sudo apt-get install redis-server
基本配置:
requirepass 123456(去掉注释,添加auth)
bind 127.0.0.1(加上注释,外部IP访问)
重启:sudo /etc/init.d/redis-server restart
ORM:jedis
使用JAVA时API的Maven依赖:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
使用redisTemplate匹配删除:(redistemplate是spring框架对jedis和lettuce的封装)
redisTemplate.delete(redisTemplate.keys("dev[0|A]*"));
常用命令:
连接:使用redis-cli连接到redis服务端,使用命令 auth **** 输入密码,使用select index选择使用的库,未指定的情况下默认选用第一个。
del key 删除任意的key。
expire key 设置key的过期时间
数据类型 | 命令 | 示例 | 说明 | value理解 | opsFor |
String | set,get,mset,mget, decr,incr(数值+1,-1操作) | value其实不仅可以是String,也可以是数字 | 普通 | void set(K key, V value); | |
Hash | hget,hset,hgetall | 127.0.0.1:6379> hset myinfo name whp age 99 sex boy (integer) 3 127.0.0.1:6379> hgetall myinfo 1) "name" 2) "whp" 3) "age" 4) "99" 5) "sex" 6) "boy" | value是一个hash表,又是各种k-v | HashMap | void putAll(H key, Map<? extends HK, ? extends HV> m); |
List(有序队列) | lpush,rpush,lpop,rpop,lrange | 127.0.0.1:6379> rpush mylist zero one two three four (integer) 5 127.0.0.1:6379> lrange mylist 0 5 1) "zero" 2) "one" 3) "two" 4) "three" 5) "four" 127.0.0.1:6379> lset mylist 0 zero! OK | 下标从零开始。 把list当成一个数组更好理解; 一边 lpush() 另一边 rpop(),list又可以作为队列使用 | 数组[]或者ArrayList;队列 | Long rightPushAll(K key, Collection<V> values); |
Set | sadd,spop,smembers,sunion | 127.0.0.1:6379> sadd myset zero one two three four (integer) 5 127.0.0.1:6379> smembers myset 1) "three" 2) "one" 3) "two" 4) "zero" 5) "four" 127.0.0.1:6379> object encoding myset "hashtable" 127.0.0.1:6379> sadd numset 1 2 3 0 1 5 (integer) 5 127.0.0.1:6379> smembers numset 1) "0" 2) "1" 3) "2" 4) "3" 5) "5" 127.0.0.1:6379> object encoding numset "intset" | set会去重,而且根据设置的value的field的类型,选择对应编码,然后自动排序。 排序对比java的TreeSet:(ascII码) [five, four, one, three, two] 排序对比java的HashSet:(Hash规则不同) [four, one, two, three, five] | java中的HashSet | Long add(K key, V... values); |
Sorted Set | zadd,zrange,zrem,zcard | 127.0.0.1:6379> zadd myzset 1 one 2 two (integer) 2 127.0.0.1:6379> zrange myzset 0 5 1) "one" 2) "two" | 指定的score来确认顺序 | -- | Long add(K key, Set<TypedTuple<V>> tuples); |
项目中缓存更新策略
- 先更新数据库,再删除缓存(这是目前业界最常用的方案)
- 先更新数据库,再更新缓存(一前一后写数据库、一后一前写缓存引起数据不是最新的)
- 先删缓存,再更新数据库
- read/write through
- 写回。在更新数据的时候,只更新缓存,不更新数据库,而我们的缓存会异步地批量更新数据库
强一致性实现:
通过2PC或是Paxos协议保证一致性;生产过程中要么保持强一致性,要么拼命的降低并发时脏数据的概率,而Facebook使用了这个降低概率的玩法,因为2PC太慢,而Paxos太复杂。
集群搭建的三种模式
- 主从复制(master写-slave读)(至少3主3从 ?)
- 哨兵模式【redis2.8】(Sentinel自动选主)(至少1主2从 paxos)
- Redis-Cluster集群模式【redis3.0】(分布式存储)
常见缓存问题
- 缓存雪崩:大范围key失效 => 设置不同的过期时间/多级缓存
- 缓存击穿【库里有】:热点key失效 => 互斥锁(读库线程加锁)
- 缓存穿透【库里没有】:设置空值一段时间/布隆过滤器
redis删除策略
定期删除(100ms随机抽查部分key)+惰性删除(get某个key的时候检查是否过期)
持久化
RDB(快照备份) / AOF(备份命令)
网友评论