网站后端的数据库随着业务的不断扩大,用户的累积,数据库的压力会逐渐增大。一种办法是优化使用方法,也就是的优化 SQL 语句啦,添加缓存以达到减少存取的目的;另外一种办法是修改使用架构,在数据库层面上「分库分表」。
以前做手游服务器的时候,数据库用的是 NxM 的结构,即 N 个数据库,M 个表。通过用户 ID 哈希把不同的用户分布到不同的表中,以达到「均衡」的目的。分库分表是很常见的解决数据库压力的方法,适用于很多业务场景,比如社交类app,用户表、用户评论这种只会不断累加但不会删除。
我遇到一个刚需的例子是:日志统计平台,当然少不了日志存储。日志的特性是相互之间没有任何关联(业务简单),一直会增量上报(量大),单表存储,很快就会有查询性能问题。这是可能最合适的分库分表的业务场景了。
ORM 几乎是数据库切分的「天敌」(本质上他们有这不同的设计策略)。而我用的是 Django,Django 的 ORM 基本上就可以「分表」说再见了,一个模型对应一个表,如果要 10 个表,就要写 10 个模型,使用上麻烦,而且不容易扩展和维护。Django 提供了同时使用多数据库的方法,通过配置路由规则来选择使用的数据库,看起来是的「垂直分库」变的可行,这篇文章将介绍在日志统计平台中如何实现日志存储的分库。
BTW,在此之前我的日志系统是我自己脱离 Django 直接封装了一层 MySQL 的使用接口,实现 10*10 的日志存储库表结构,用了一段时间也没出现问题。缺陷就是增加新功能的时候太过繁琐,为不同业务的查询封装了多个接口,最蛋疼的时候没有 django migrate 这样的工具,增加、删除字段会变的很复杂。
日志统计平台有自身的业务,以及其它要存储的数据用 default 来存储,日志自身的存储将被分成 10 个库,然后按照服务器 ID 哈希到这 10 个库中。库的别名为 sharding0, sharding1, ..., sharding9。
新建项目
首先创建一个 logstat 的项目,然后一个创建 report 的 app。
>>> django-admin startproject logstat
>>> cd logstat
>>> django-startapp report
数据库配置
配置 setting 中配置 default DATABASES:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'logstat',
'USER': 'logstat_user',
'PASSWORD': 'logstat_password',
'HOST': 'localhost',