环境准备
操作系统
JVM与应用服务器
周边依赖系统
数据库
拓扑
根据扩展性原则考虑:
-
垂直拆分:按业务将表拆分到不同的库。
-
水平拆分:水平分库分表。
-
读写分离:在业务允许的情况下,在从库读取非实时数据。
-
海量数据表的定期归档:主要有利于DDL变更及数据备份。查询时如命中索引差别不大
Schema:
数据库DDL SQL 遵循DBA的MySQL DDL/DML Review标准 ,使用了DBA Tools Schema Review审查,性能相关的要求包括:
-
统一的存储引擎,主键策略。
-
禁用存储过程,函数,触发器,外键约束。
-
列类型建议:布尔/枚举:tinyint,日期与时间戳:timestamp或int,char/lob: 尽量用varchar(n),小数及货币:移位转为int 或 decimal,IP地址:int(依赖函数转换)。
-
索引策略:索引字段的顺序需要考虑字段值去重之后的个数,较多的放前面,合理创建联合索引,合理利用覆盖索引等。
根据尽量少数据原则与尽量少交互的原则来设计SQL:
-
禁止select *
-
合理的SQL语句,减少交互次数
根据扩展性原则,将负载放在更容易伸缩的应用服务实例上:
-
尽量不要做数学运算,函数运算, 或者输出格式转换等非必要操作
-
避免count(*),计数统计实时要求较强使用memcache或者redis,非实时统计使用定时更新的单独统计表。
-
甚至排序都是不鼓励的,尽量在应用侧进行。另外避免多余的排序,使用GROUP BY 时,默认会进行排序,当你不需要排序时,可以使用order by null。
MySQL设计标准(红色的为必须遵守的)
DDL设计标准
SQL语句标准
读写分离使用标准
1、需在设计阶段考虑如果访问量非常大,且不做scale out表拆分的话,需读写分离,但读写分离注意主从复制有延迟的可能性; 参考 是否采用读写分离方案的讨论
索引使用标准
1、非唯一索引建议使用“idx_表缩写名称_字段缩写名称”进行命名。
2、唯一索引建议使用“uniq_表缩写名称_字段缩写名称”进行命名。
3、索引名称必须使用小写。
4、唯一键不和主键重复。每个业务实体表和关系表都应该至少有一个业务主键对应的唯一索引。
5、索引字段的顺序需要考虑字段值去重之后的个数,个数多的放在前面,就是数据分布。
6、使用EXPLAIN判断SQL语句是否合理使用索引,尽量避免extra列出现:Using File Sort,Using Temporary。
7、UPDATE、DELETE语句需要根据WHERE条件添加索引。
8、合理创建联合索引(避免冗余),(a,b,c) 相当于 (a) 、(a,b) 、(a,b,c)。
9、合理利用覆盖索引。比如SELECT email,uid FROM user_email WHERE uid=xx,如果uid不是主键,适当时候可以将索引添加为index(uid,email),以获得性能提升。
约束设计
a) 主键的内容不能被修改。
b) 外键约束一般不在数据库上创建,只表达一个逻辑的概念,由程序控制。
d) 禁用数据库外键
命名
a) 主键约束:默认PRIMARY;
b) unique约束:UK_<column_name>
c) check约束: CK_<column_name>
d) 外键约束: 业务禁用
RabbitMQ
-
当消息的吞吐量达到单个物理Queue的速度上限(3000tps)时,应该考虑分片功能,或者业务暂时没有达到很大的吞吐,在可以预见的将来能达到非常高的吞吐,也应该尽早设计为分片模式;
-
如非必要情况,应该保持默认的同步发送模式;
-
在设计channel和queue绑定的routekey时,考虑消息的业务类型与routekey的关联,使得routekey能够体现业务特征;
-
如果有必要关注消费者如下参数:autocommit(自动提交确认,默认false) 、prefetchCount(预取消息条数,默认64条),autocommit设置为true将在消息拉取到本地即认为消费成功,而不是真正消费成功后提交。