Redis高性能缓存数据库
Redis高性能缓存数据库
- Redis 基础入
- Redis 介绍
- 特性
- 使用场景
- 正确安装与启动
- 重要的指令使用
- 全局命令
- 单线程架构
- 字符串 - String
- 内部编码
- 应用场景
- 哈希 - Hash
- 内部编码
- 应用场景
- 三种方案实现用户信息存储优缺点
- 列表 - List
- 集合 - SET 用户标签,社交,查询有共同兴趣爱好的人,智能推荐
- 命令
- 集合的交集
- 集合的并集(集合合并去重)
- 内部编码
- 使用场景
- 有序集合 - ZSET
- 命令
- 有序集合交集
- 有序集合并集(合并去重)
- 有序集合内部编码
- 使用场景
- Redis 缓存雪崩与穿
- 什么是雪崩?
- 解决方案
- 什么是穿透?
- 解决方案
- Redis 持久化
- bgsave 运行流程
- RDB 文件的操作
- AOF 持久化
- redis 的 AOF 配置详解
- 如何从 AOF 恢复?
- redis 重启时恢复加载 AOF 与 RDB 顺序及流程:
Redis 基础入
Redis 介绍
- redis 是一种基于键值对(key-value)数据库,其中 value 可以为 string、hash、list、
set、zset 等多种数据结构,可以满足很多应用场景。还提供了键过期,发布订阅,事务,
流水线,等附加功能; - 流水线:Redis 的流水线功能允许客户端一次将多个命令请求发送给服务器, 并将
被执行的多个命令请求的结果在一个命令回复中全部返回给客户端,使用这个功能可以
有效地减少客户端在执行多个命令时需要与服务器进行通信的次数。
特性
- 速度快,数据放在内存中,官方给出的读写性能 10 万/S,与机器性能也有关;
1.1 数据放内存中是速度快的主要原因
1.2 C 语言实现,与操作系统距离近
1.3 使用了单线程架构,预防多线程可能产生的竞争问题 - 键值对的数据结构服务器;
- 丰富的功能:见上功能;
- 简单稳定:单线程;
- 持久化:发生断电或机器故障,数据可能会丢失,持久化到硬盘;
- 主从复制:实现多个相同数据的 redis 副本;
- 高可用和分布式:哨兵机制实现高可用,保证 redis 节点故障发现和自动转移;
- 客户端语言多:java php python c c++ nodejs 等。
使用场景
- 缓存:合理使用缓存加快数据访问速度,降低后端数据源压力
- 排行榜:按照热度排名,按照发布时间排行,主要用到列表和有序集合
- 计数器应用:视频网站播放数,网站浏览数,使用 redis 计数
- 社交网络:赞、踩、粉丝、下拉刷新
- 消息队列:发布和订阅
正确安装与启动
- linux 上安装,windows 也能装,但我们以 linux 环境为主;
- 配置、启动、操作、关闭;
可执行文件 | 作用 |
---|---|
redis-server | 启动redis |
redis-cli | redis 命令行客户 |
redis-benchmark | 基准测试工具 |
redis-check-aof | AOF持久化文件检测和修复工具 |
redis-check-dump | RDB 持久化文件检测和修复工具 |
redis-sentinel | 启动哨兵 |
- redis-server 启动
3.1 默认配置:redis-server, 日志输出版本信息,端口 6379
3.2 运行启动:redis-server --port 6380 不建议
3.3 配置文件启动: ./redis-server redis.conf,灵活,生产环境使用这种 - redis-cli 启动
4.1 交互式:redis-cli -h {host} -p {prot}连接到 redis 服务,没有 h 默认连 127.0
redis-cli -h 127.0.0.1 -p 6379 //没有 p 默认连 6379
4.2 命令式:redis-cli -h 127.0.0.1 -p 6379 get hello //取 key=hello 的 value
4.3 停止 redis 服务: redis-cli shutdown
注意:
a.关闭时:断开连接,持久化文件生成,相对安全
b.还可以用 kill 关闭,此方式不会做持久化,还会造成缓冲区非法关闭,可能会造成AOF 和丢失数据
c.关闭前生成持久化文件: 使用 redis-cli -a 123456 登录进去,再 shutdown nosave|save
重大版本:
1.版本号第二位为奇数,为非稳定版本(2.7、2.9、3.1)
2.第二为偶数,为稳定版本(2.6、2.8、3.0)
3.当前奇数版本是下一个稳定版本的开发版本,如 2.9 是 3.0 的开发版本
重要的指令使用
全局命令
- 查看所有键:keys * set school enjoy set hello world
- 键总数 dbsize
2 个键,如果存在大量键,线上禁止使用此指令 - 检查键是否存在:exists key
存在返回 1,不存在返回 0 - 删除键:del key;
del hello school, 返回删除键个数,删除不存在键返回 0 - 键过期:expire key seconds //set name test expire name 10
10 秒过期ttl 查看剩余的过期时间 - 键的数据结构类型:type key
返回 string,键不存在返回 none
单线程架构
- 列举例子:三个客户端同时执行命令
客户端 1:set name test
客户端 2:incr num
客户端 3:incr num - 执行过程:发送指令-〉执行命令-〉返回结果
- 执行命令:单线程执行,所有命令进入队列,按顺序执行,使用 I/O 多路复用解决 I/O 问题,后面有介绍(通过 select/poll/epoll/kqueue 这些 I/O 多路复用函数库,我们解决了一个线程处理多个连接的问题)
- 单线程快原因:纯内存访问, 非阻塞 I/O(使用多路复用),单线程避免线程切换和竞争产生资源消耗
- 问题:如果某个命令执行,会造成其它命令的阻塞
字符串 - String
- 字符串类型:实际上可以是字符串(包括 XML JSON),还有数字(整形 浮点
数),二进制(图片 音频 视频),最大不能超过 - 设值命令:
set age 23 ex 10 //10 秒后过期 px 1000
setnx name test //不存在键 name 时,返回 1 设置成功;存在的话失败 0
set age 25 xx //存在键 age 时,返回 1 成功
场景:如果有多客户同时执行 setnx,只有一个能设置成功,可做分布式锁
获值命令:get age //存在则返回 value, 不存在返回 nil
批量设值:mset country china city beijing
批量获取:mget country city address //返回 china beigjin, address 为 nil 若没有 mget 命令,则要执行 n 次 get 命令
使用 mget=1 次网络请求+redis 内部 n
- 计数:
incr age //必须为整数自加 1,非整数返回错误,无 age 键从 0 自增返回 1
decr age //整数 age 减 1
incrby age 2 //整数 age+2
decrby age 2//整数 age -2
incrbyfloat score 1.1 //浮点型 score+1 - append 追加指令:
set name hello; append name world
追加后成 helloworld - 字符串长度:set hello “世界”;strlen hello结果 6,每个中文占 3 个字节
- 截取字符串:set name helloworld ; getrange name 2 4//返回 llo
内部编码
int:8 字节长整理//set age 100; object encoding age //返回 int
embstr:小于等于 39 字节串 set name bejin; object encodeing name//embstr
raw:大于 39 字节的字符串 set a fsdfwerwerweffffffffffdfs//返回
应用场景
键值设计:业务名:对象名 id:[属性]
数据库为 order, 用户表 user,对应的键可为 order:user:1 或 order:user:1:name
注意:redis 目前处于受保护模式,不允许非本地客户端链接,可以通过给 redis
设置密码,然后客户端链接的时候,写上密码就可以了
127.0.0.1:6379> config set requirepass 123456 临时生效
或者修改 redis.conf requirepass 123456,启动时./redis-server redis.conf 指定 conf
./redis-cli -p 6379 -a 12345678 //需要加入密码才能访问
切换数据库:select 2
哈希 - Hash
是一个 string 类型的 field 和 value 的映射表,hash 特适合用
命令 hset key field value
设值:hset user:1 name james //成功返回 1,失败返回 0
取值:hget user:1 name //返回 james
删值:hdel user:1 age //返回删除的个数
计算个数:hset user:1 name james; hset user:1 age 2
hlen user:1 //返回 2,user:1 有两个属性值
批量设值:hmset user:2 name james age 23 sex boy //返回 OK
批量取值:hmget user:2 name age sex //返回三行:james 23 boy
判断 field 是否存在:hexists user:2 name //若存在返回 1,不存在返回 0
获取所有 field: hkeys user:2 // 返回 name age sex 三个 field
获取 user:2 所有 value:hvals user:2 // 返回 james 23 boy
获取 user:2 所有 field 与 value:hgetall user:2 //name age sex james 23 boy 值
增加 1:hincrby user:2 age 1 //age+1
hincrbyfloat user:2 age 2 //浮点型加
内部编码
ziplist<压缩列表>和 hashtable<哈希表>
当 field 个数少且没有大的 value 时,内部编码为 ziplist
如:hmset user:3 name james age 24; object encoding user:3 //返回 ziplist
当 value 大于 64 字节,内部编码由 ziplist 变成 hashtable
如:hset user:4 address “fsgst64 字节”; object encoding user:3 //返回 hashtab
应用场景
比如将关系型数据表转成 redis 存储:
使用 hash 后的存储方式
如果有值为 NULL,那么如下:
HASH 类型是稀疏,每个键可以有不同的 filed, 若用 redis 模拟做关系复杂查询开发
因难,维护成本高
三种方案实现用户信息存储优缺点
- 原生:
set user:1:name james;
set user:1:age 23;
set user:1:sex;
优点:简单直观,每个键对应一个值
缺点:键数过多,占用内存多,用户信息过于分散,不用于生产环境 - 将对象序列化存入 redis
set user:1 serialize(userInfo);
优点:编程简单,若使用序列化合理内存使用率高
缺点:序列化与反序列化有一定开销,更新属性时需要把 userInfo 全进行反序列化,更新后再序列化到 redis - 使用 hash 类型
hmset user:1 name james age 23 sex boy
优点:简单直观,使用合理可减少内存空间消耗
缺点:要控制 ziplist 与 hashtable 两种编码转换,且 hashtable 会消耗更多内存
总结:对于更新不多的情况下,可以使用序列化,对于 VALUE 值不大于 64 字节
可以使用 hash 类型
列表 - List
- 用来存储多个有序的字符串,一个列表最多可存 2 的 32 次方减 1 个元素
因为有序,可以通过索引下标获取元素或某个范围内元素列表,列表元素可以重复 - 列表命令
类型 | 指令 |
---|---|
添加 | rpush lpush linsert |
查 | lrange lindex llen |
修改 | lset |
删除 | lpop rpop lrem ltrim |
阻塞 | blpop brpop |
添加命令:
rpush james c b a //从右向左插入 cba, 返回
lrange james 0 -1 //从左到右获取列表所有元素 返回 c b a
lpush key c b a //从左向右插入 cba
linsert james before b teacher //在 b 之前插入 teacher, after为之后,使用 lrange james 0 -1 查看:c teacher b a
查找命令:
lrange key start end //索引下标特点:从左到右为 0 到 N-1
lindex james -1 //返回最右末尾 a,-2 返回 b
llen james //返回当前列表长度
lpop james //把最左边的第一个元素 c 删除
rpop james //把最右边的元素 a 删除
lrem key count value//删除指定元素
如:
lpush test b b b b b j x z //键 test 放入 z x j b b b b b
lrange test 0-1 //查询结果为 z x j b b b b b
lrem test 4 b //从左右开始删除 b 的元素,删除 4 个,若 lrem test 8 b, 删除 8 个 b, 但只有 5 个全部删除 lrange test 0 -1 //删除后的结果为 b j x z
lrem test 0 b //检索所有 b 全部删除 j x z
lpush user b b b b b j x z //键 user 从左到右放入 z x j b b b b b
ltrim user 1 3 //只保留从第 2 到第 4 的元素,其它全删
lrange user 0 -1 //查询结果为 x j b, 其它已全被删掉
lpush user01 z y x //键 user01 从左到右放入 x y z
lset user01 2 java // 把第 3 个元素 z 替换成 java
lrange user01 0 -1 //查询结果为 x y java
集合 - SET 用户标签,社交,查询有共同兴趣爱好的人,智能推荐
保存多元素,与列表不一样的是不允许有重复元素,且集合是无序,一个集合最多
可存 2 的 32 次方减 1 个元素,除了支持增删改查,还支持集合交集、并集、差集;
命令
exists user //检查 user 键值是否存在
sadd user a b c//向 user 插入 3 个元素,返回 3
sadd user a b //若再加入相同的元素,则重复无效,返回 0
smembers user //获取 user 的所有元素,返回结果无序
srem user a //返回 1,删除 a 元素
scard user //返回 2,计算元素个数
sismember user a //判断元素是否在集合存在,存在返回 1,不存在 0
srandmember user 2 //随机返回 2 个元素,2 为元素个数
spop user 2 //随机返回 2 个元素 a b,并将 a b 从集合中删除
smembers user //此时已没有 a b, 只有 c
集合的交集
sadd user:1 zhangsan 24 girl
sadd user:2 james 24 boy//初始化两个集合
sinter user:1 user:2 //求两集合交集, 此时返回
sadd user:3 wang 24 girl //新增第三个元素
sinter user:1 user:2 user:3 //求三个集合的交集,此时返回 24
集合的并集(集合合并去重)
sunion user:1 user:2 user:3 //三集合合并(并集),去重 24
sdiff user:1 user:2//1 和 2 差集,(zhangsan 24 girl)-(james 24 boy)=zhangsan girl
将交集(jj)、并集(bj)、差集(cj)的结果保存:
sinterstore user_jj user:1 user:2 //将 user:1 user:2 的交集保存到 user_jj
sunionstore user_bj user:1 user:2 //将 user:1 user:2 的(并)合集保存 user_bj
sdiffstore user_cj user:1 user:2 //将 user:1-user:2 的差集保存 user_cj
smemebers user_cj // 返回 zhangsan girl
内部编码
sadd user 1 2 3 4 //当元素个数少(小于 512 个)且都为整数,redis 使用 intset
减少内存的使用
sadd user 1 2…513 //当超过 512 个或不为整数(比如 a b)时,编码为 hashtable
object encoding user //hashtables
使用场景
标签,社交,查询有共同兴趣爱好的人,智能推荐
使用方式:
给用户添加标签:
sadd user:1:fav basball fball pq
sadd user:2:fav basball fball
…
或给标签添加用户
sadd basball:users user:1 user:3
sadd fball:users user:1 user:2 user:3
…
计算出共同感兴趣的人:
sinter user:1:fav user2:fav
规则:sadd (常用于标签) spop/srandmember(随机,比如抽奖)
sadd+sinter (用于社交,查询共同爱好的人,匹配)
有序集合 - ZSET
常用于排行榜,如视频网站需要对用户上传视频做排行榜,或点赞数
与集合有联系,不能有重复的成员
命令
zadd key score member [score member…]
zadd user:zan 200 james //james 的点赞数 1, 返回操作成功的条数 1
zadd user:zan 200 james 120 mike 100 lee// 返回 3
zadd test:1 nx 100 james //键 test:1 必须不存在,主用于添加
zadd test:1 xx incr 200 james //键 test:1 必须存在,主用于修改,此时为 300
zadd test:1 xx ch incr -299 james //返回操作结果 1,300-299=1
zrange test:1 0 -1 withscores //查看点赞(分数)与成员名
zcard test:1 //计算成员个数, 返回 1
查点赞数
zadd test:2 nx 100 james //新增一个集合
zscore test:2 james //查看 james 的点赞数(分数),返回 100
排名
zadd user:3 200 james 120 mike 100 lee//先插入数据
zrange user:3 0 -1 withscores //查看分数与成员
lee | mike | james |
---|---|---|
100 | 120 | 200 |
zrank user:3 james //返回名次:第 3 名返回 2,从 0 开始到 2,共 3 名
zrevrank user:3 james //返回 0, 反排序,点赞数越高
删除成员
zrem user:3 jame mike //返回成功删除 2 个成员,还剩 lee
增加分数
zincrby user:3 10 lee //成员 lee 的分数加 10
zadd user:3 xx incr 10 lee //和上面效果一样
返回指定排名范围的分数与成员
zadd user:4 200 james 120 mike 100 lee//先插入数据
zrange user:4 0 -1 withscores //返回结果如下图
zrevrange user:4 0 -1 withscores //倒序,结果如下图
返回指定分数范围的成员
zrangebyscore user:4 110 300 withscores //返回 120 lee ,200 James, 由低到高
zrevrangebyscore user:4 300 110 withscores //返回 200james 120lee,由高到低
zrangebyscore user:4 (110 +inf withscores//110 到无限大,120mike 200james
zrevrangebyscore user:4 (110 -inf withscores//无限小到 110,返回 100 lee
返回指定分数范围的成员个数
zcount user:4 110 300 //返回 2,由 mike120 和 james200 两条数据
删除指定排名内的升序元素
zremrangebyrank user:4 0 1 //分数升序排列,删除第 0 个与第 1 个,只剩 james
删除指定分数范围的成员
zadd user:5 200 james 120 mike 100 lee//先插入测试数据
zremrangebyscore user:5 100 300 //删除分数在 100 与 300 范围的成员
zremrangebyscore user:5 (100 +inf //删除分数大于 100(不包括 100),还剩 lee
有序集合交集
格式:
zinterstore destination numkeys key … [WEIGHTS weight] [AGGREGATE SUM|MIN|MA
destination:交集产生新的元素存储键名称
numkeys: 要做交集计算的键个数
key :元素键值
weights:每个被选中的键对应值乘 weight, 默认为 1
初始化数据:
zadd user:7 1 james 2 mike 4 jack 5 kate //初始化 user:7 数据
zadd user:8 3 james 4 mike 4 lucy 2 lee 6 jim //初始化 user:8 数据
交集例子:
zinterstore user_jj 2 user:7 user:8 aggregate sum //2 代表键合并个数,
//aggregate sum 可加也不可加上,因为默认是 sum
//结果 user_jj:4james(1+3), 6mike(2+4)
zinterstore user_jjmax 2 user:7 user:8 aggregate max 或 min
//取交集最大的分数,返回结果 3james 4mike, min 取最小
weights:
zinterstore user_jjweight 2 user:7 user:8 weights 8 4 aggregate max
//1,取两个成员相同的交集,user:7->1 james 2 mike; user:8->3 james 4 mike
//2,将 user:7->james 18=8, user:7->mike 28 =16, 最后 user:7 结果 8 james 16 mike;
//3,将 user:8-> james 34=12, user:8->mike 44=16最后 user:8 结果 12 james 16 mike
//4,最终相乘后的结果,取最大值为 12 james 16mike
//5, zrange user_jjweight 0 -1 withscores 查询结果为 12 james 16mike
总结:
将 user:7 成员值乘 8,将 user:8 成员值乘 4,取交集,取最大
有序集合并集(合并去重)
格式:
zunionstore destination numkeys key … [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
destination:交集产生新的元素存储键名称
numkeys: 要做交集计算的键个数
key :元素键值
weights:每个被选中的键对应值乘 weight, 默认为 1
zunionstore user_jjweight2 2 user:7 user:8 weights 8 4 aggregate max
//与以上 zinterstore 一样,只是取并集,指令一样
有序集合内部编码
ziplist: zadd user:9 20 james 30 mike 40 lee
object encoding user:init
//当元素个数少(小于 128 个),元素值小于 64 字节时,
使用 ziplist 编码,可有效减少内存的使用skiplist: zadd user:10 20 james…
//大于 128 个元素或元素值大于 64 字节时为 skiplist 编码
使用场景
排行榜系统,如视频网站需要对用户上传的视频做排行榜
点赞数:zadd user:1:20180106 3 mike //mike 获得 3 个
再获一赞:zincrby user:1:20180106 1 mike //在 3 的基础上加 1
用户作弊,将用户从排行榜删掉:zrem user:1:20180106 mike
展示赞数最多的 5 个用户:
zadd user:4:20160101 9 jack 10 jj 11 dd 3 james 4 lee 6 mark 7 kate
zrevrangebylex user:4:20160101 + - limit 0 5查看用户赞数与排名:
zscore user:1:20180106 mike zrank user:1:20180106 mik
Redis 缓存雪崩与穿
什么是雪崩?
前提:
为节约内存,Redis 一般会做定期清除操作
- 当查询 key=james 的值,此时 Redis 没有数据
- 如果有 5000 个用户并发来查询 key=james,全到 Mysql 里去查, Mysql 会挂掉,导致雪崩
解决方案
- 设置热点数据永远不过期。
- 加互斥锁
什么是穿透?
前提:黑客模拟一个不存在的订单号 xxxx
- Redis 中无此值
- Mysql 中也无此值, 但一直被查询
解决方案
- 对订单表所有数据查询出来放到布隆过滤器, 经过布隆过滤器处理的数据很小(只存 0 或1)
- 每次查订单表前,先到过滤器里查询当前订单号状态是0还是1, 0的话代表数据库没有数据, 直接拒绝查询
Redis 持久化
- redis 支持 RDB 和 AOF 两种持久化机制,持久化可以避免因进程退出而造成数据丢失;
- RDB 持久化把当前进程数据生成快照(.rdb)文件保存到硬盘的过程,有手动触发和自动触发
- 手动触发有 save 和 bgsave 两命令
save 命令:阻塞当前 Redis,直到 RDB 持久化过程完成为止,若内存实例比较大
会造成长时间阻塞,线上环境不建议用它
bgsave 命令:redis 进程执行 fork 操作创建子线程,由子线程完成持久化,阻塞时
间很短(微秒级),是 save 的优化,在执行 redis-cli shutdown 关闭 redis 服务时,如果没有开
启 AOF 持久化,自动执行 bgsave;
显然 bgsave 是对 save 的优化
bgsave 运行流程
RDB 文件的操作
命令:config set dir /usr/local //设置 rdb 文件保存路径
备份:bgsave //将 dump.rdb 保存到 usr/local 下
恢复:将 dump.rdb 放到 redis 安装目录与 redis.conf 同级目录,重启 redis 即可
优点:
- 压缩后的二进制文,适用于备份、全量复制,用于灾难恢复
- 加载 RDB 恢复数据远快于 AOF 方式
缺点:
- 无法做到实时持久化,每次都要创建子进程,频繁操作成本过高
- 保存后的二进制文件,存在老版本不兼容新版本 rdb 文件的问题
AOF 持久化
针对 RDB 不适合实时持久化,redis 提供了 AOF 持久化方式来解决
开启:redis.conf 设置:appendonly yes (默认不开启,为 no)
默认文件名:appendfilename “appendonly.aof”
流程说明:
- 所有的写入命令(set hset)会 append 追加到 aof_buf 缓冲区中
- AOF 缓冲区向硬盘做 sync 同步
- 随着 AOF 文件越来越大,需定期对 AOF 文件 rewrite 重写,达到压缩
- 当 redis 服务重启,可 load 加载 AOF 文件进行恢复AOF持久化流程:命令写入(append),文件同步(sync),文件重写(rewrite),重启加载(load)
redis 的 AOF 配置详解
appendonly yes //启用 aof 持久化方式
appendfsync always //每收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
appendfsync everysec //每秒强制写入磁盘一次,性能和持久化方面做了折中,推荐
appendfsync no //完全依赖 os,性能最好,持久化没保证(操作系统自身的同步)
no-appendfsync-on-rewrite yes //正在导出 rdb 快照的过程中,要不要停止同步 aof
auto-aof-rewrite-percentage 100 //aof 文件大小比起上次重写时的大小,增长率100%时,重写
auto-aof-rewrite-min-size 64mb //aof 文件,至少超过 64M 时,重写
如何从 AOF 恢复?
- 设置 appendonly yes;
- 将 appendonly.aof 放到 dir 参数指定的目录;
- 启动 Redis,Redis 会自动加载 appendonly.aof 文件。
redis 重启时恢复加载 AOF 与 RDB 顺序及流程:
- 当 AOF 和 RDB 文件同时存在时,优先加载
- 若关闭了 AOF,加载 RDB 文件
- 加载 AOF/RDB 成功,redis 重启成功
- AOF/RDB 存在错误,redis 启动失败并打印错误信息
Redis高性能缓存数据库相关推荐
- 高薪程序员必备—Redis高性能缓存数据库
欢迎关注专栏:Java架构技术进阶.里面有大量batj面试题集锦,还有各种技术分享,如有好文章也欢迎投稿哦.微信公众号:慕容千语的架构笔记.欢迎关注一起进步. (一)什么是Redis? Redis是一 ...
- 知乎技术分享:从单机到2000万QPS并发的Redis高性能缓存实践之路
本文来自知乎官方技术团队的"知乎技术专栏",感谢原作者陈鹏的无私分享. 1.引言 知乎存储平台团队基于开源Redis 组件打造的知乎 Redis 平台,经过不断的研发迭代,目前已经 ...
- Redis一通百通~P8架构师带你玩转Redis高性能缓存设计实战
前言 高并发十分考验架构师功底,它也是分布式架构设计中必须考虑的因素之一.要知道,光靠服务器堆是没有出路的. 想看看大牛是怎么面对高并发的?想知道BATJ大厂是怎么设计高可用架构的?这里有可参考的实践 ...
- 从单机到2000万 QPS 并发的 Redis 高性能缓存实践之路
1.引言 知乎存储平台团队基于开源Redis 组件打造的知乎 Redis 平台,经过不断的研发迭代,目前已经形成了一整套完整自动化运维服务体系,提供很多强大的功能.本文作者陈鹏是该系统的负责人,本次文 ...
- 掌握Redis高性能key-value数据库
目录 Redis 简介 Redis 优势 Redis与其他key-value存储有什么不同? Redis 典型应用场景 Redis常见的数据结构 Redis 对比 memcached 安装Redis ...
- Redis入门指南:深入了解这款高性能缓存数据库
本文将带您了解Redis的基本概念.数据类型.特性以及如何在实际项目中应用Redis.通过阅读本文,您将更好地理解如何利用Redis优化您的应用程序性能. 1. 什么是Redis? 2. Redis的 ...
- Spring Boot 整合Redis 实现缓存
本文提纲 一.缓存的应用场景 二.更新缓存的策略 三.运行 springboot-mybatis-redis 工程案例 四.springboot-mybatis-redis 工程代码配置详解 运行环境 ...
- Spring Boot 整合 Redis 实现缓存操作
摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 产品没有价值,开发团队再优秀也无济于事 – <启示录> 』 本文提纲 一.缓 ...
- mysql springboot 缓存_Spring Boot 整合 Redis 实现缓存操作
摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 产品没有价值,开发团队再优秀也无济于事 – <启示录> 』 本文提纲 一.缓 ...
最新文章
- RequireJS学习笔记(转)
- 第十九课.基于sklearn的SVM人脸识别
- Hyperledger Fabric 核心模块(5)peerer共识
- java steam 去重_Java中对List去重, Stream去重
- Win7性能信息和工具在哪打开
- Flask学习笔记02:实现用户登录功能
- sqlite3用python家外键_Django/Sqlite3为带有外键的模型添加一行
- 小计C/C++问题(1)
- Windows 2003 EE升级服务错误号:0x8DDD0018 解决办法
- 微软卸载工具msicuu2(附带资源)
- java之NIO简介
- 模板引擎?看这一篇就懂了
- 服务器无线桥接怎么设置,路由器怎么设置桥接方法 2个路由器无线桥接设置图解...
- RFID技术是怎么构成的,主要分为哪几部分?
- .net 操作达梦数据库
- C#按汉字拼音首字母排序
- 测试用例经典设计方法之 因果图法
- 查看TensorFlow checkpoint文件中的变量名和对应值
- netcore docker for windows build image,push docker hub(linux pull镜像运行容器)
- SVM详解(三)支持向量机使用核技巧
热门文章
- Android Studio混淆相关总结
- 0PP0升级android版本,oppo哪些手机可以升级安卓11 oppo手机升级安卓11方法
- 2021-09-15小记西数3T蓝盘翻车
- Watchguard Firebox 配置DKEY动态口令认证
- 加载天地图服务出现空吧图片类似404图片加载失败的效果
- Unity 检测手机性能,区分高中低端机型
- 紫外线检测仪UVA、UVB、UVC、UVA2紫外线检测仪WKM-UV1
- Unity 移动键Q的三种用法 For Mac,Windows类同
- java俄罗斯方块英文书籍_Java版俄罗斯方块
- 名额有限| 和喜马拉雅、网易严选、大搜车...学运营,是超级用户运营!