生成唯一ID-雪花算法:https://github.com/godruoyi/php-snowflake](https://github.com/godruoyi/php-snowflake)
一、高并发的问题,我们该关心什么
1、QPS :每秒钟请求或查询的数量(QPS 不等于并发连接数 并发连接数是系统同时处理请求的数量)
2、吞吐量:单位时间内处理的请求数量(通常由QPS和并发数决定)
3、响应时间
4、PV:综合浏览量(Page View),即页面浏览量或者点击量,一个访客24小时内访问的页面数量,
同一个人浏览网站的同个页面多次刷新,只记做一个PV
5、UV:独立访客(Unique Visitor),即一定时间范围内相同的访客多次访问网站,只计算为1个UV
6、带宽:日网站带宽 = PV/统计时间(换算成秒)* 平均页面大小(单位KB)* 8
7、峰值的QPS := (总PV数 * 80%)/(6小时秒数 * 20%)
8、压力测试:ab、wrk、http_load、Apache JMeter
二、 不同QPS下的优化
1、QPS达到100,数据库缓存、数据库负载均衡
2、QPS达到800,如果网站带宽为100M,那么带宽就会吃完。CDN加速、负载均衡
3、QPS达到1000, 如果使用Memcache缓存,Memcache的悲观锁并发2W左右,那么内网的带宽可能以及吃完。静态HTML缓存
4、QPS达到2000,文件系统访问锁成为了灾难,做业务分离、分布式存储
三、优化方案
1、流量优化。防盗链
2、前端优化。减少http请求、添加异步请求、开启浏览器缓存和文件压缩、CND加速、建立独立图片服务器、
3、服务端优化。页面静态化、并发处理(队列、异步)
4、数据库优化。数据库缓存、分库分表分区、读写分离、负载均衡
5、web服务器优化。负载均衡、
四、具体的优化方案
1、防盗链:使用Referer请求地址判断或者签名
Referer nginx配置
location ~.*\.(gif|jpg|png|flv|swf|rar|zip)$
{
valid_referers none blocked test.com *.test.com;
if($invalid_referer){
#return 403;
rewrite ^/ http://www.test.com/403.jpg;
}
}
加密签名:使用第三方模块HttpAccessKeyModule实现Nginx防盗链
location ~.*\.(gif|jpg|png|flv|swf|rar|zip)$
{
accesskey on;
accesskey_hashmethod md5; #加密算法,和php的加密算法保持一直
accesskey_arg "sign"; #url请求签名的参数名
accesskey_signatrue "mypass$remote_addr"; #加密规则 md5( 'mypass'+客服端的ip地址);
}
2、数据库优化
- 数据库类型的正确选择
- 数据表引擎的不同
InnoDB:默认事务型引擎,性能优秀。
数据存储共享表空间(索引等),可通过配置分开
主键查询性能高于其他类型的引擎
通过一些机制和工具支持真正的热备份
支持崩溃后 的安全恢复
支持行级锁
支持外键
MyISAM
支持全文索引
不支持事务和行级锁,表锁
不支持崩溃后 的安全恢复
表存储在2个文件,MYD和MYI
查询效果比较高
统计效率比较高(count)
- MySQL索引,主键、唯一索引、联合索引 的区别,以及对数据库性能的影响
1、索引对性能的影响
大大减少服务器需要扫描的数据量‘
帮助服务器避免排序和临时表
将随机I/O 变成顺序的I/O
大大提高查询速度
缺点:降低写的速度,占用磁盘
2、索引的使用场景
对于小的表,全表扫描效率更高
中大型的表,索引非常有效
特大型的表,建立索引和使用索引代价也会提高,可使用分区技术解决
3、主键索引和唯一索引的区别
一个表只能有一个主键,可以有多个唯一索引
主键索引一定是唯一索引,唯一索引不是主键索引
主键可以和外键构成参照完整性约束,防止数据不一致
4、索引的创建原则
where中的列,或者连接子句中的列
索引列基数越大,索引效果越好
对字符串进行索引,应该制定一个前缀长度,可以节省大量空间
根据情况创建复合索引,复合索引可以提高查询效率
避免创建过多的索引,索引或占用磁盘空间,降低写的效率
主键尽可能使用较短的类型,比比如整型
5、索引生效
. 复合联合索引的原则(前缀原则 ) key(a,b,c)
. 索引生效:where a=1 and b =2 and c=3
where a=1 and b=2
where a=1 其他都不生效
. ike 查询,%不能在前,可以使用全文索引
. is not null 和 is null 不走索引
. order by 加上索引
. != 索引失效
. 如果MySQL估计使用索引比全表扫描慢,会放弃使用索引
. or 前面会使用索引,后面不会,可以使用UNION ALL来代替
select * from temp where age=20 or age=30;不走索引,可以使用下面的代替
select * from temp where age=20
UNION ALL
select * from temp where age=30
. 列类型是字符串,查询时一定要给值加引号,否则索引失效
.
6、SQL优化
. 不要select *
. 谨慎使用模糊查询。只有 s% (%在后面)才走索引
. 对order by 加索引
. 少用IS NULL和IS NOT NULL 不走索引 可以使用>或者<代替
. 少用!=运算符 可以使用>和< 代替
. 少用OR; OR前面会使用索引,后面不会,可以使用UNION ALL来代替
select * from temp where age=20 or age=30;不走索引,可以使用下面的代替
select * from temp where age=20
UNION ALL
select * from temp where age=30
. 少用 IN 和NOT IN
select * from user where age in(20,30); 可以使用下面的代替
select * from user where age= 20
UNION ALL
select * from user where age=20
. 避免条件语句中的数据类型转换
如果数据类型是整型,不要加引号
. 在表达式左侧使用运算符和函数会是索引失效