《高并发系统设计40问》阅读笔记: 数据库/缓存/消息队列/分布式服务

本篇目录

说明

这个专栏比较一般,涉及的内容比较多(数据库/缓存/消息队列/分布式服务),但是蜻蜓点水,不如分别阅读每个方向的专栏,实战篇的三个案例挺好,值得学习。

试读链接任意四章试读入口

新人优惠极客时间新注册38元代金券

唐扬《高并发系统设计40问》

基本方法

  1. 水平扩展
  2. 缓存
  3. 异步

阿里巴巴的系统分层方法:

阿里巴巴系统分层规范

数据库优化

数据库优化方法:

  1. 使用数据库连接池,避免每次新建连接
  2. 主从复制,读写分离,主从延迟处理方法
  3. 数据库分库(垂直拆分):将多个表拆分到多个数据库中
  4. 数据库分表(水平拆分):将一个表拆分到多个数据库中
  5. 使用NoSQL方法:1. 具被水平扩展能力,mongo/es等 2. 如果需要模糊查询,使用基于倒排索引的 ES

主从延迟处理方法:

  1. 编码设计时,通过数据冗余的方式避免写入后立即查询
  2. 写数据库时,同步写入缓存
  3. 直连主库

分库分表后注意事项:

  1. 查询需要带有分区字段,否则会查询所有数据库
  2. 无法跨库 join
  3. 聚合查询性能变差,例如count()
  4. 不能用自增ID作为全局唯一主键

全局唯一主键获取方法:

  1. 使用 Snowflake 算法生成
  2. uuid 的问题:不是单调递增的

聚簇索引与基于LSM树的存储引擎:

  1. 聚簇索引中,索引和数据同时存储,数据插入更新导致随机IO,页分裂时需要移动数据
  2. LSM树牺牲读性能提高写性能:用多个有序的 SSTable 文件存储,写入时先写入 MemTable,然后择机生成/合并 SSTable

缓存优化

各类操作耗时:ssd磁盘读取耗时是内存读取耗时的1万倍。

操作耗时

缓存会引入数据不一致的问题。

Cache Aside 策略:

  1. 读取时,如果缓存中存在使用缓存数据,否则查询数据库并更新缓存
  2. 更新时,先更新数据库,然后删除缓存
  3. 如果并发操作A在B进行更新前读取了旧数据,B删除缓存后,A才开始更新缓存,这时会出现数据不一致。
  4. 一种解决方法是「延迟双删」:B更新数据库前删除缓存,更新数据库后等等一段实际,再删一次缓存。(这种方法可以降低数据不一致的概率,但不能完全避免)

Write Through 策略:

  1. 更新时,缓存中有对应数据,直接更新缓存,然后缓存组件负责将更新同步到数据库
  2. 更新时,缓存中无对应数据,方式一(Write allocate),写入缓存,缓存组件负责同步到数据库,方式二(No-Write alocate),直接更新数据库

Read Through 策略:

  1. 读取时,如果缓存中不存在对应数据,由缓存组件负责从数据库中加载

缓存穿透/缓存击穿的处理方法:

  1. 回种空值,对应数据不存在时,在缓存中写入空值,这种方式会增加缓存空间的使用量(大量空值数据)
  2. 使用布隆过滤器,将所有存在的ID经过hash、取模后映射到二进制bit数组中,查询时先用布隆过滤器判断是否存在。布隆过滤器判定不存在则一定不存在,但是不存在的记录有可能被判定为存在

极热缓存失效后出现大量穿透的问题的处理(狗桩效应/ dog-pile effect) :

  1. 设置一个简单的分布式锁(例如 redis 的 setnx),穿透到数据库之前,先获取分布式锁,避免大量并发请求同时穿透数据库

消息队列

这章讲的很一般,没有什么实质性内容,建议阅读另一个专栏: 李玥《消息队列高手课》

分布式服务

这部分也泛泛而谈

多机房部署

北京同地双机房专线延迟:1ms~3ms。

国内异地双机房专线延迟:50ms内,北京到天津 10ms,北京到上海 30ms,北京到广州 50ms。

跨国双机房:100ms~200ms。

同城双活方案

同城双活方案

同城双活数据库方案:

  1. 主库部署在一个机房,另一个机房服务跨机房写库(延迟1~3ms)
  2. 每个机房都有从库,每个机房中的服务读取各自的从库
  3. 主库所在机房故障,另一个机房的从库提升为主库
  4. 服务间调用请求发送到同机房

实战案例

海量计数器的设计

根据 微博2020年用户发展报告,2020年9月微博日活跃用户 2.24 亿,每天 2 亿人次登陆微博,可以推断微博全平台里的微博数量非常庞大。每一条微博都要记录对应都转发数、评论数、点赞数、浏览数等等,即要实现海量的计数器。

  1. 阶段1: 建立一张计数表,以微博ID为主键,记录每个微博的相应计数
  2. 阶段2:以微博ID为分区键,选用哈希算法,进行分库分表
  3. 阶段3:抛弃数据库,以微博ID为 key,只在 redis 中保留计数器数据(引入丢数据风险)
  4. 阶段4:改造 redis,使用自定义的数据接口,降低内存占用
  5. 阶段5:改造 redis,实现冷热数据分离,将不经常访问的数据转移到 ssd 磁盘

高QPS的未读数设计

未读数是分别呈现给不同的用户的未读消息数,未读消息可能是一批针对所有用户的消息,例如系统通知,也可能是每个用户订阅的特定消息,例如关注的微博用户。

全员推送消息的场景:

  • 面向全部用户的推送的消息是所有用户共享的一组有序消息列表,分别记录每个用户已阅的最后一个消息
  • 用全局消息列表总数减去当前用户的最后一个已阅消息位置,得出当前用户的未读消息数

用户订阅消息的场景:

  • 不同用户的订阅目标不同,未读消息数不同
  • 在缓存中快照用户上一时刻关注的所有用户发布的消息数,用这些被关注用户的当前消息数减去该用户上一时刻的快照,得出当前用户的未读消息数

信息流的推拉模式

用户A发布一条消息后,需要尽快让关注它的 B/C/D 等收到消息:

推模式:

  1. 为 B/C/D 等每个人建立一个收件箱,将 A 发布的消息推送到所有粉丝的收件箱中
  2. B/C/D 获取信息流的操作简化,直接读取各自的收件箱即可
  3. 如果A的粉丝数量非常多,譬如千万乃至上亿,A 每发一条消息,会产生等量的写入

拉模式:

  1. B 同时关注了 A/C/D,A/C/D 发送消息时,是在各自的发件箱中记录一次
  2. B 获取信息流时,从构成关注关系的 A/C/D 的发件箱中查询消息
  3. 如果 B 关注的用户非常多,譬如几千个,每次要查询上千用户的已发布消息。解决方法:将每个用户最近5天的消息ID以用户ID为key,存放到缓存中

参考

  1. 李佶澳的博客
  2. 微博2020年用户发展报告

系统设计

  1. Netflix 的异地多活设计: Active-Active for Multi-Regional Resiliency
  2. Facebook 的缓存系统实践经验《Scaling Memcache at Facebook》
  3. 多机数据系统的正确性与一致性
  4. 《大型网站技术架构: 核心原理与案例分析》阅读摘录
  5. 《分布式金融架构课》阅读笔记2: 线性一致的分布式数据系统的实现过程
  6. 《分布式金融架构课》阅读笔记1: 单机&多机并发/多副本读写正确性和一致性
  7. 《消息队列高手课》阅读笔记: Rabbit/Rocket/Kafka/模型/消息事务/保序等
  8. 《消息队列高手课》阅读笔记: Rabbit/Rocket/Kafka/模型/消息事务/保序等
  9. 《Redis核心技术与实践》阅读笔记: 数据类型/存储开销/Rehash/案例等
  10. 《Redis核心技术与实践》阅读笔记: 数据类型/存储开销/Rehash/案例等
  11. 《高并发系统设计40问》阅读笔记: 数据库/缓存/消息队列/分布式服务
  12. 《高并发系统设计40问》阅读笔记: 数据库/缓存/消息队列/分布式服务
  13. 《MySQL实战45讲》阅读笔记: 索引类型/数据可靠性/事务/间隙锁/临时表等
  14. 系统性能分析方法论: 统计图谱工具
  15. 张磊《深入剖析Kubernetes》专栏的阅读笔记
  16. 代理服务软件haproxy、nginx、envoy对比,以及开源的API网关项目对比
  17. 蓝绿部署、金丝雀发布(灰度发布)、A/B测试的准确定义
  18. 阿里巴巴的应用限流和服务降级是怎样实现的?|如何打造平台稳定能力
  19. 陈皓《左耳听风》专栏的阅读笔记(持续更新)
  20. 好雨云帮,一款不错的国产开源PaaS
  21. 怎样为软件的不同版本命名?
  22. 怎样选择开源项目的license?
  23. Glusterfs的架构
  24. 怎样设计一个企业级的PaaS平台?
  25. 几种常见的LDAP系统
  26. DNS SRV介绍(一种用DNS做服务发现的方法)
  27. DNS,DNS-Domain Name System
  28. 思科的网络设备
  29. 虚拟化技术汇总
  30. 认证与授权系统的汇总
  31. 高可用实现方法汇总
  32. 编译器汇总
  33. Linux系统的优化方法
  34. CentOS7的一些变化
  35. 分布式系统的一些知识
  36. 计算机编程语言的特性汇总
  37. 网络通信的一些基础知识
  38. PCIE总线的一些知识
  39. 操作系统的API
  40. 网卡的一些知识
  41. Linux系统的构建过程
  42. 数据结构与算法
  43. CPU的相关知识

系统设计

  1. Netflix 的异地多活设计: Active-Active for Multi-Regional Resiliency
  2. Facebook 的缓存系统实践经验《Scaling Memcache at Facebook》
  3. 多机数据系统的正确性与一致性
  4. 《大型网站技术架构: 核心原理与案例分析》阅读摘录
  5. 《分布式金融架构课》阅读笔记2: 线性一致的分布式数据系统的实现过程
  6. 《分布式金融架构课》阅读笔记1: 单机&多机并发/多副本读写正确性和一致性
  7. 《消息队列高手课》阅读笔记: Rabbit/Rocket/Kafka/模型/消息事务/保序等
  8. 《消息队列高手课》阅读笔记: Rabbit/Rocket/Kafka/模型/消息事务/保序等
  9. 《Redis核心技术与实践》阅读笔记: 数据类型/存储开销/Rehash/案例等
  10. 《Redis核心技术与实践》阅读笔记: 数据类型/存储开销/Rehash/案例等
  11. 《高并发系统设计40问》阅读笔记: 数据库/缓存/消息队列/分布式服务
  12. 《高并发系统设计40问》阅读笔记: 数据库/缓存/消息队列/分布式服务
  13. 《MySQL实战45讲》阅读笔记: 索引类型/数据可靠性/事务/间隙锁/临时表等
  14. 系统性能分析方法论: 统计图谱工具
  15. 张磊《深入剖析Kubernetes》专栏的阅读笔记
  16. 代理服务软件haproxy、nginx、envoy对比,以及开源的API网关项目对比
  17. 蓝绿部署、金丝雀发布(灰度发布)、A/B测试的准确定义
  18. 阿里巴巴的应用限流和服务降级是怎样实现的?|如何打造平台稳定能力
  19. 陈皓《左耳听风》专栏的阅读笔记(持续更新)
  20. 好雨云帮,一款不错的国产开源PaaS
  21. 怎样为软件的不同版本命名?
  22. 怎样选择开源项目的license?
  23. Glusterfs的架构
  24. 怎样设计一个企业级的PaaS平台?
  25. 几种常见的LDAP系统
  26. DNS SRV介绍(一种用DNS做服务发现的方法)
  27. DNS,DNS-Domain Name System
  28. 思科的网络设备
  29. 虚拟化技术汇总
  30. 认证与授权系统的汇总
  31. 高可用实现方法汇总
  32. 编译器汇总
  33. Linux系统的优化方法
  34. CentOS7的一些变化
  35. 分布式系统的一些知识
  36. 计算机编程语言的特性汇总
  37. 网络通信的一些基础知识
  38. PCIE总线的一些知识
  39. 操作系统的API
  40. 网卡的一些知识
  41. Linux系统的构建过程
  42. 数据结构与算法
  43. CPU的相关知识

推荐阅读

Copyright @2011-2019 All rights reserved. 转载请添加原文连接,合作请加微信lijiaocn或者发送邮件: [email protected],备注网站合作

友情链接:  系统软件  程序语言  运营经验  水库文集  网络课程  微信网文  发现知识星球