MySQL 的优化方案
一、代码中 sql 语句优化
容易
二、数据库字段优化,索引优化
容易
三、池化技术(针对 GORM 框架)
减少频繁创建数据库连接,从而降低对数据库的性能损耗
优化的核心:
空闲值和最大值参数的设置
对数据库连接池进行预热,避免未预热导致系统重启后产生较多的慢请求
池化的核心是空间换时间,需要特别关注空间占用情况。避免内存泄露和频繁的 GC (初期使用 pporf 针对性的优化一下)
TODO:
准备预热池化技术的脚本
四、加缓存,redis 等
具体方案在 redis 中
五、主从分离
可以解决突发的数据库读流量,属数据库横向扩展。
数据价值性上看,可选择的方案有两种
高价值:
PXC 方案
低价值:
Replcation
具体选择看项目
主从分离网络上看
主从分离,一主多从
风险以及解决方案:
风险:主从读写分离,一主多从后,可能会造成写入数据之后立刻读的时候读取不到的情况。
解决方案(针对Go):
kingshard
flike/kingshard
小米的 Gaea
XiaoMi/Gaea
TODO:
调研其他方案
对上述两个备选做测试
需要根据项目需要权衡的点:
性能与主从一致性之间的权衡
主从延迟的可能性:
需要监测主从延迟的数据。(写入成功,但读取不到数据时,需要考虑的点之一),最终得到相对合适的延迟时间
六、分库分表
针对数据库容量瓶颈和写并发量大的应对措施
垂直拆分和水平拆分
风险:
会引入诸如查询数据必须带上分区键,列表总数需要单独冗余存储等问题。
需要了解的是在实现分库分表过程中,数据从单库单表迁移多库多表是一件即繁杂又容易出错的事情,而且如果初期没有规划得当,后面要继续增加数据库数或者表数时,还要经历这个迁移的过程。
分库分表的原则
如果在性能上没有瓶颈点那么就尽量不做分库分表;
如果要做,就尽量一次到位
考虑 NoSQL 替代的方案。(运维要求高)
如何保证分库分表后 ID 的全局唯一性?
Snowflake
七、优化 mysql server
mysql 内存管理优化
#修改相应服务器位置的配置文件 my.cnf
key_buffer_size
决定myisam索引块缓存区的大小,直接影响表的存取效率,建议1/4可用内存
read_buffer 读缓存
write_buffer 写缓存
log 机制及优化
innodb_buffer_pool_size 存储引擎表数据和索引数据的最大缓存区大小
innodb_old_blocks_pct LRU算法 决定old sublist的比例
innodb_old_blocks_time LRU算法 数据转移间隔时间
调整 mysql 并发参数
max_connections 最大连接数,默认151
back_log 短时间内处理大量连接,可适当增大
table_open_cache 控制所有SQL执行线程可打开表缓存的数量,受其他参数制约
thread_cache_size 控制缓存客户服务线程数量,加快数据库连接速度,根据threads_created/connections来衡量是否合适
innodb_lock_wait_timeout 控制事务等待行锁时间,默认50ms
给出 Go 分段加锁的 Demo,做备用
强化各层面的运维熟悉度以及纠错排查能力
TODO
Redis 则考虑 Redisson
Go 使用分段加锁
分布式情况下锁的性能优化方案
RocketMq架构高性能设计思路hosaos的博客-CSDN博客rocketmq 如何实现高性能
RocketMQ 的设计与优化方案
如何保证redis的高并发及高可用?
详细的
Redis 的优化方案
// 暂不考虑
数据迁移方案
// 暂不考虑
CDN 加速静态资源
回种空值是一种最常见的解决思路,实现起来也最简单,如果评估空值缓存占据的缓存空间可以接受,则可优先使用该方案;
布隆过滤器会引入一个新的组件,也会引入一些开发上的复杂度和运维上的成本。所以只有在存在海量查询数据库中,不存在数据的请求时才会使用,在使用时也要关注布隆过滤器对内存空间的消耗;
对于极热点缓存数据穿透造成的 “狗桩效应”,可以通过设置分布式锁或者后台线程定时加载的方式来解决。
核心:在于减少对于数据库的并发请求
缓存穿透应对方案
依项目实际情况确定
具体选择:
客户端方案
通过制定一些数据分片和数据读写的策略,可以实现缓存高可用。
优点:没有性能损耗
缺点:客户端逻辑复杂且在多语言环境下不能复用。
中间代理方案
客户端和缓存节点之间增加了中间层,在性能上会有一些损耗,在代理层会有一些内置的高可用方案。
服务端方案
Redis Sentinel
保障缓存高可用的方案
Cache Aside 分布式缓存常用策略
Read/Write Through 和 Write Back 策略需要缓存组件的支持,比较适合在实现本地缓存组件的时候使用;
Write Back 策略是计算机体系结构中的策略,不过写入策略中的只写缓存,异步写入后端存储的策略倒是有很多的应用场景。
缓存策略的选择
关注的点:缓存命中率,读写比例
原则:需要将请求尽量挡在上层,因为越往下层,对于并发的承受能力越差
根据项目评估是否需要多级缓存
承担 MySQL 的压力
缓存
需要结合实际调整