高并发设计
2024-02-21 11:21:37 0 举报
AI智能生成
高并发设计 高并发架构 高并发
作者其他创作
大纲/内容
高性能
高并发
failover故障转移
超时控制
限流
降级
高可用
三高
发号器:如何保证分库分表后ID的全局唯一性?
Snowflake 算法完全可以弥补 UUID 存在的不足,因为它不仅算法简单易实现,也满足 ID 所需要的全局唯一性,单调递增性,还包含一定的业务上的意义。
背景
生成的数据不具备单调递增性,也就是无序的,如果需要排序就会有弊端
空间浪费
ID有序也会提升数据写入性能
不利于问题排查
不具备业务含义
为何不适用UUID
问题
发号器
静态缓存
memcached
redis
分布式缓存
当我们遇到极端的热点数据查询的时候
热点本地缓存
分类
适用于读多写少的业务场景,并且数据最好带有一定的热点属性
带来整体系统复杂度,会有数据不一致的风险
内存不是无限的
运维成本
不足
写数据:先更新数据库,再删除缓存
读:先查询缓存,再查询数据库
方法
解决了主从复制延迟的问题
优点
缓存中数据频繁被清理,对命中率有一定影响
缺点
写数据时更新完数据库,再更新缓存,增加分布式锁,但是对写会造成性能影响
更新数据库时更新缓存,增加较短的过期时间
优化方案
旁路缓存
就是对缓存的 Key 做哈希计算,然后对总的缓存节点个数取余
Hash 分片算法
以很好地解决增加和删减节点时,命中率下降的问题
一定要设置缓存的过期时间
脏数据问题
引入虚拟节点的概念。
分布不均匀
一致性 Hash 分片算法
写入数据时,进行数据分片
读数据时,利用多组的缓存来做容错,主从副本两种策略
在客户端配置多个缓存的节点,通过缓存写入和读取算法策略来实现分布式,从而提高缓存的可用性。
客户端方案
在应用代码和缓存节点之间增加代理层,客户端所有的写入和读取的请求都通过代理层,而代理层中会内置高可用策略,帮助提升缓存系统的高可用。
中间代理层
就是 Redis 2.4 版本后提出的 Redis Sentinel 方案。
服务端方案
高可用方案
缓存没有,数据库没有
会给这个空值加一个比较短的过期时间,让空值在短时间之内能够快速过期淘汰
大量空值数据,浪费空间,建议评估缓存容量是否支持
回种空值
我们把集合中的每一个值按照提供的 Hash 算法算出对应的 Hash 值,然后将 Hash 值对数组长度取模后得到需要计入数组的索引值,并且将数组这个位置的值从 0 改成 1。在判断一个元素是否存在于这个集合中时,你只需要将这个元素按照相同的算法计算出索引值,如果这个位置的值为 1 就认为这个元素在集合中,否则则认为不在集合中。
思路
时间复杂度O(1)
20亿数组 只需要238M
空间也很少
判断元素在集合中时,这个元素可能不在集合中
一旦布隆过滤器判断这个元素不在集合中时,它一定不在集合中
hash碰撞导致错误几率
不支持删除
缺陷
选择多个 Hash 函数计算多个 Hash 值,这样可以减少误判的几率;
布隆过滤器会消耗一定的内存空间,所以在使用时需要评估你的业务场景下需要多大的内存,存储的成本是否可以接受。
对于极热点缓存数据穿透造成的“狗桩效应”,可以通过设置分布式锁或者后台线程定时加载的方式来解决。
建议
布隆过滤器
解决方案
缓存穿透
适用于空数据有限
空值回填
访问不存在的数据,绕过缓存,直接到数据库,数据也没有数据
含义
互斥锁
不设置过期时间
业务逻辑,将key的过期时间存储,请求是否小于该值
不过期
热点key过期,大量请求击穿到DB
缓存击穿
随机时间
后台更新
限流+本地缓存
双缓存
同一时刻大量缓存失效(故障)
缓存雪崩
cache redis
write back
read/write through
数据一致性
拆分复杂结构
迁移热点
多副本
热点数据
缓存预热
子主题
缓存降级
常见问题
缓存
存储
动态变更推送
注册中心
服务注册与发现
将一些服务共有的功能整合,独立部署,用来解决服务治理的问题
屏蔽服务部署地址和协议细节
限流、熔断、降级、分流等
植入服务治理策略
客户端的认证和授权
黑名单等等
日志记录
分布式链路追踪
作用
入口网关
调用网布API时统一认证、授权、审计、访问控制
出口网关
IO模型
性能
责任链模式
扩展性
线程隔离
线程池
如何实现
kong
zuul
tyk
开源实现
流量网关
业务网关
独立出专用的服务聚合、超时控制组网关
抽象独立服务层,做接口聚合的事情
接口聚合处理方案
API网关
请求响应时间
延迟
吞吐量
通信量
错误
服务或资源达到上线的程度
饱和度
内容
agent
埋点
开源工具
如何收集
消息队列承接
kibana展示
数据写入ES
spark
strom
流式处理
两个队列
数据处理和存储
服务监控
如何设计一个支持高并发大存储量的计数系统
实战
横向扩展
异步
通用设计
空间换时间
数据库连接池等
解决连接复用问题
池化技术
查询主库
冗余信息
一般延迟再一百毫秒以内,如果出现秒级别需要注意
同步延迟
主从复制
中间件对数据源管理
缺点性能问题
mycat独立部署方案
缺点语言支持问题
TDDL嵌入式代码
如何保证无感数据访问
主从读写分离
单表数据量千万甚至上亿级别
索引文件占用磁盘空间过大,无法缓存全量索引信息,从而影响查询性能
备份和恢复时间边长
不同模块数据都在一个主库,一旦故障,都会受影响
将数据库的表拆分到多个不同的数据库中。
一般是按照业务类型来拆分,核心思想是专库专用,将业务耦合度比较高的表拆分到单独的库中
垂直拆分
将单一数据表按照某一种规则拆分到多个数据库和多个数据表中,关注点在数据的特点
按照字段哈希值拆分,适用于实体表
按照某一字段区间拆分,例如时间
规则
水平拆分
方式
引入了分库分表键,也就是分区键,也就是我们对数据库做分库分表所依据的字段。
性能没有瓶颈,尽量不要分库分表
如果做就一步到位,满足几年的业务需求
很多nosql数据库,提供了自动sharding特性,可以采用nosql代提关系型数据库
原则
分库分表
数据库
传统关系型数据库弊端
提升写入性能
提升扩展性
特点
副本集
分片
负载均衡
mongo
NOSQL
削峰填谷
异步处理
解耦合
重传机制
消息生产过程中丢失数据
异步刷盘
kafka集群备份,保证消息不丢失
但是异步刷盘,发生故障还是容易丢,可以减少刷盘间隔,会对性能有影响
不要开启异步刷盘,而是使用kafka集群方式
如果需要确保消息一条都不能丢
建议不部署集群
如果有一定容忍度
方案
在消息队列中丢失
在消费过程中丢失
消息丢失
kafka原生支持,这个特性保证消息虽然在生产端重复,但是消息队列只会存储一份
消息生产过程中
存储,查询是否存在后,再处理
通用层
版本号
乐观锁
业务层
消费端
幂等
如何确保消息一定被送到,且只被消费一次?
消息队列中堆积数量过多,导致数据几个小时都无法被处理和返回
监控
消费性能问题
消息队列
轮训
待权重的轮训
静态策略
有限连接数最少服务
响应时间权重等
动态策略
策略
存活检测
故障检测
同城双活
异地多活
多机房部署
最好线上环境和数据进行压测
拷贝流量方式
不能使用模拟请求,使用线上流量
不要从一台服务器发起流量
注意点
高并发大流量下,进行的压测
定义
流量隔离
风险控制
关键点
流量构建和产生
压测数据隔离模块
系统健康度检查和压测流量干预模块
模块
全链路压测平台
压测
高并发设计
0 条评论
回复 删除
下一页