1 简介
大厂的应用,服务器和数据库的压力基本持平,中小型软件,服务器压力没有数据库压力大。
将一部分推拉数据功能模块转化为通过服务器缓存或计算去完成,从而将数据库压力转移到服务器。
本文讨论的主要内容包括:
1)通过服务器缓存和计算转移部分数据库压力;
2)创建索引提高检索效率,但注意避免影响更新速度;
3)减少不必要的数据库交互,利用缓存和计算来减轻数据库负载;
4)采用数据库分库分表和主从读写分离架构来提升数据库性能,应对高并发;
5)使用集中式协调器处理分布式事务。
以上方案也无法降低数据库压力时,还可以凭借分布式数据库,主从读写分离数据库支持横向扩展能力,提升数据库性能,理论上横向扩展数据库性能可以无上限提高数据库承压能力。
因此从代码层,中间层,分布式三个分析分析如何优化数据库使用,提升应用系统性能。
2 在代码层面消化数据库压力
- 索引
索引是MySQL和Oracle等数据库本身提供的功能,合理创建索引可以提高数据的检索效率,降低数据库服务器IO和CPU的消耗。
但由于索引也会降低更新表的速度,经常增删改的表或字段不适合创建索引.
所以在开发初期,我们就应该根据数据库模型表和字段的作用来决定是否为该表建立索引,为数据记录较多的表中,频繁作为查询条件的字段建立索引。
class Article(models.Model):
"article model"
title = models.CharField('title',max_length=200,)
class Meta:
indexes = [models.Index(fields=['title']),]
3 转移压力
在代码层把数据库压力转移到服务器上,要求我们在编写代码的时候,时刻留意代码中是否有过多与数据库进行交互的行为,是否可以通过缓存或计算,来减少与数据库交互的次数。
如一个功能模块的代码写下来,发现多次连接数据库,可以调整为一次性取出所有需要的数据,减少对数据库的查询次数。
又如模块中的某一个值,既可以通过逻辑运算得出,也可以通过数据库读取,在为减轻数据库压力的场景下,我们会选择前者。
4 数据库分库分表
上面几种方法是在应用系统的软实力上做文章,达到为数据库减压的目的,但面对真正庞大的流量袭来时,还是得下硬功夫——提升数据库自身的读写性能。
纵向提高数据库配置,加CPU、加内存,对性能的提升是有限的,幸运的是,目前大部分数据库都支持分布式架构,或主从读写分离架构。
分布式架构数据库由多个计算机系统设备共同组成一个数据库,提供完整的数据库服务,
例如Oracle、MongoDB、TDSQL等,增加计算机系统的数量,就能提升整体数据库性能,理论上分布式架构数据库的性能可以无限提高,这就是为什么大型电商能承受几十亿并发压力的原因之一。
5 主从读写分离架构
主从读写分离架构是专门一个主数据库用来写入数据,另外搭建几个从数据库用于读取数据.
主数据库会把数据的变更同步给几个从数据库,这样就能将数据库的读取压力分散到多台从数据库中,从而实现数据库的减压。
相比于前面几种方案,横向提高数据库性能的成本高昂,并且主库的能力到位了,分库才更能体现价值,产品优化到位了,分布式架构横向扩展的性价比才高,“软实力”和“硬功夫”两者需要有机结合。
6 集中协调器
分布式事务访问一个或多个分区中的数据,这需要昂贵的协调。
集中式协调器充当协调所有行为的全局“警察”。
中间件
集中式协调器可用作中间件,接受查询请求并将查询路由到正确的分区。权力下放协调员
在去中心化方法中,节点自行组织。客户端直接将查询发送到其中一个分区。
此主分区会将结果发送回客户端。具体分区负责与其他分区通信并相应地提交。
集中式方法让位于多个客户端尝试获取锁的瓶颈在相同的分区上。
对于分布式 2PL 来说可能更好,因为它具有锁的中央视图并且可以处理死锁更快。
对于分散的方法来说,这并非易事。
7 使用辅助工具
能否合理使用中间件和辅助工具,是考量一个技术经理能力的标准之一,选择和利用各种合适中间件的优势,可以有效提高产品性能,减少资源消耗。在数据读取压力较大的场景中,往往会引入Redis和MQ中间件。
缓存redis
Redis缓存数据库是将数据以键值对的形式缓存在内存中的高效数据库。
在开发中,我们可以将一些频繁读取的数据临时存放到Redis,例如中签公告、人员名单、产品清单等,用户在访问这些数据的时候,如果发现缓存中有数据,则无需调用数据库,直接从Redis获取。
同时,由于内存的读写速率是普通机械硬盘的几百倍,使用Redis作为数据缓存不仅减轻了数据库的压力,数据的存取速度还特别快,可以有效提高数据的调取速率。
- 队列MQ的使用
MQ消息队列中间件常用于流量消峰和消息分发。
利用MQ将同一时刻的大量请求分散成一段时间来处理,可以有效减轻数据库负担;
另外把消息发布到MQ中供多个客户端监听,也能达到减少数据查询次数的效果。