提高数据库服务读写性能

提高数据库服务读写性能

单台(机)数据库

一般数据库读写是系统的瓶颈,也是优化收益最高的,单点最多的
1.查询优化:针对select,以下维度

  • 主键查询 千万条记录1-10ms
  • 唯一索引 千万条记录10-100ms;与唯一索引的差别为非聚簇索引,需要增加一次寻址
  • 普通索引(非唯一) 千万条记录100-1000ms
  • 无 百万条记录1000ms+

2.批量写:插入无法使用索引时的优化,批量写是优化收益最高的一种方案

  • for each {insert into table values () },损耗最高,建议换成Execute once insert into table values (),(*),…;
    以下维度
  • sql 编译一次与N的时间与空间复杂度
  • 网络消耗的时间复杂度
  • 磁盘寻址的复杂度

3.索引优化,查看往期 https://blog.csdn.net/weixin_49759486/article/details/123120024

4.innodb存储引擎优化;配置优化

  • max_connection=1000 增加最大连接数,之前的版本默认为100,在海量的数据库对接的应用服务器集群当中太少,1000位经验判断,还是需要根据物理机器资源情况作比较
  • innodb_file_per_table=1可以存储每个innodb表和它的索引和b+树独立在自己的文件中,减少寻址和读写的开销
  • innodb_buffer_pool_size=1G缓存池大小,此参数非常关键,设置为当前数据库服务内存的60-80%;决定innodb性能的好坏
  • innodb_log_file_size=256M一般取256M可以兼顾性能和recovery的速度,写满后只能切换日志靠buffer存储;刷新时提交磁盘数据,设置大时会延迟log_file被打印满之后所造成的事务卡顿,太大的话recovery的速度就会变慢,所有一般设置256
  • innodb_log_buffer_size=16M 此参数也很重要,该参数确保有足够大的日志缓冲区来保证脏数据在被写入到日志文件之前可以继续mysql事务操作,也可以存储日志的中间数据
  • innodb_flush_log_at_trx_commit=2
    设置0时,效率更高但安全性差。每秒才write日志,任何mysql进程的崩溃会删除崩溃前最后一秒的事务。
    设置1时,在每个事务提交时,日志缓冲被写到日志文件,对日志文件做到磁盘操作的刷新。Truly ACID。速度慢。一般不会设置为1.
    设置2时,在每个事务提交时,日志缓冲被写到系统缓冲(打开操作系统的文件句柄,写到一个系统文件当中),但不对日志文件做到磁盘操作的刷新。然后根据innodb_flush_log_at_timeout(默认为1秒)时间flush disk只有操作系统崩溃或掉电才会删除最后一秒的事务,不然不会丢失事务。一般设置为2,并且启用备用电源尽可能的规避掉最后一秒数据的丢失问题
  • innodb_data_file_path-ibdata1:1G;ibdata2:1G;ibdata3:1G:autoextend 指定表数据和讴吟存储的空间,可以使一个或多个文件;做数据归档使用;表示提前设置3个,之后自动增长,保证每个文件不会太大,降低磁盘寻址的时间。

MySQL读写分离

master和slave通过bin log同步,写时候写入master,读slave

  • 一主多从;一个master对应多个slave;读操作开启事务会路由到master,未开启事务路由到slave
  • 读库延迟问题处理;mysql基本可以同步到ms级别
  • 主从切换处理;master异常时可以将其中一个slave提升为master;mysql提供了半同步的解决方案:至少一个slave同步成功,master才提交事务,寻找bin log最靠前的

分库分表

  • 垂直拆分:同类型的放在一起,join三层以内,小表驱动大表,不要夸库join
  • 水平拆分:同一张表拆成多分数据,例如以不同的时间拆分成不同的表
  • 多主多从

缓存穿透、击穿、雪崩

  • 穿透:数据库中数据不存在,前段用户或者上游服务去访问不存在的数据,造成缓存的形同虚设,每次都查询数据库;尝试设置无效标志位代表数据不存在到缓存
  • 击穿:同一数据击穿到数据库,同时访问同一数据时缓存不存在直接查询数据库,数据库数据存在,但是同一时间多个请求,缓存刚好到期的情况,多个请求都会查询数据库;使用排队队列解决,缓存不存在时查询放到队列中聚集一下;也可同一数据加锁
  • 雪崩:不同的数据击穿到数据库,造成整个缓存服务的宕机;大批量的key同一时间失效,同一时间超多请求;不让大批量的key同一时间失效+randow;

缓存脏读和多级缓存

1.脏数据问题

  • 脏读产生的原因:数据更新而缓存未更新
  • 脏读如何避免:后台数据更新时,通知缓存,可清楚或直接更新
    2.多级缓存
  • 前台:前段页面,比如提前静态化好html放到cdn中,数据更新时更新cdn,可以保留一个check做紧急下架动作等
  • 中台:nginx;java建议放在java堆内或者堆外处理逻辑
  • 后台:redis和mysql,redis作缓存

版权声明:本文为qq_38847545原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。