标签:内置函数 分离 冲突 而不是 模块 信息 极限 git 失效
后端优化分为三个方向
以 Nginx、PHP、MySQL 为例。
LNMP中web高并发优化配置以及配置详解
https://phpartisan.cn/news/55.html
从简单粗暴的角度,就是提高连接数。
增加进程数,每个 CPU 配置一个进程。
进程数配置项: worker_processes
CPU 配置项: worker_cpu_affinity ,该选项使得 Nginx 每个进程都执行在不同 CPU
提高单进程允许的最多连接数。
配置项: worker_connections
理论上一台机器的最大连接数 = worker_processes * worker_connections
总体思想是控制进程数。
选项:pm
每个 PHP-FPM 进程大致占用 20 MB 的内存,用内存除以 20 MB 就是极限数量。但是要注意,如果设置极限数量,在有其他应用占用较大内存时,会导致服务异常。
去掉没有用到的扩展。
启用 OPCache 扩展。
MySQL 的内存缓存大小对于性能的影响较大。
MySQL 的缓存分为两部分:
配置项是: innodb_buffer_pool_size
这也是索引不能加太多的原因。索引加太多会导致索引占用更多的缓存,进而使得行记录的缓存减少。
索引的更多优化:
索引不要加到重复数据多的列上。
索引有一个参数 Cardinality,用于评估索引中唯一值的数目的估值。如果该值和表行数的比值小于一定程度,则不会使用索引。
字段太长应使用部分索引。
使用短 ID 作为主键。因为辅助索引的叶子节点存储的是主键,如果主键太大,会使得辅助索引也变大。因此通常使用自增 ID 而不是 UUID 作为主键。
必要情况下创建联合索引。多条件情况下,单表只会命中其中一个单列索引。
瓶颈主要在数据库。
使用双 Nginx 服务器(或者更多),用上 Keepalived + VIPA 组合确保高可用。
可以设置多个 VIPA ,分布到不同机器上,这些机器互为主备。接着让域名同时解析到这些 VIPA。这样可以充分利用多台 Nginx 服务器,并且保证高可用。
从读性能和写性能两方面入手。
提高读性能:
后台访问的服务如果是大数据服务,则可为这台机器设置更多索引来提升读性能。但会给运维带来维护的麻烦,所以慎用。通常来说保持与其他服务器相同的配置。
注:所有数据冗余都会带来数据一致性的问题。
两种一致性问题:
主从不一致
缓存不一致(Redis)
发生在写后立即读。缓存了旧数据。
通过 binlog 了解主从同步进度,同步完删除缓存。
提高写性能:
分库:
无状态化,可根据需要横向扩容。
用 JWT(Json Web Token)验证身份。
文件存储放分布式文件存储上面,如 MinIO。
分为:
例如项目中有一个模块,要传输脚本到目标机器上执行。分为两步:
要建立两次连接。
优化方式:将脚本 base64_encode,然后把执行命令拼接在后面。
echo "base64_encoded string" | base64 -d -i > /usr/local/src/xxx.sh; bash xxx.sh "param0";
碰到有多个耗时任务,为每个任务创建一个新的线程或者进程执行。
分为应用内缓存和外置缓存。
应用内缓存有些场景需要自己维护多台机器之间的缓存信息,根据情况使用。
外置缓存(如 Redis/Memcached)。
将请求外部接口的数据缓存到 Redis,减少接口调用的耗时。
总体思想是尽可能减少数据量,尽可能早结束查询,尽可能命中索引,尽可能减小锁的粒度。
在执行语句前,先用 Explain 查看执行计划,尽量命中索引,避免全表扫描。
尽量避免使用 select *,需要多少字段拿多少字段
非唯一索引尽量使用 limit
使用索引来代理 limit 处理分页
limit 会扫描前面不要的数据,然后逐一抛弃。在 Where 里面指定 ID 范围会更快。
业务层提供上一页和下一页的操作,避免用户一次跳多页。URL 要使用 after_xxx ,避免用户直接修改 page。例如 GitHub 的 release 列表界面。
用 Union 替代 OR
注:MySQL 的优化器会尝试使用索引合并来自动优化 OR。
当数据集不会重复时,用 Union All 替代 Union
联合索引最左匹配原则
联合索引在范围查询的字段后就不会再走索引了
删除由最左匹配原则覆盖的索引
使用 like 时,避免把 % 放前面
放在前面不走索引。
使用 Where 加更精确的条件限制来减少传输的数据量
以前见过判断用户登录用户名密码的时候,把整个用户表查出来再逐一判断的代码。
避免对索引列使用 MySQL 内置函数。
优先使用 Inner Join 而不是其他 Join。
如果使用 Left Join 或者 Right Join,驱动表数据量尽可能小。
避免在索引列上使用不等号。如果索引能用范围扫描,则使用范围操作符。
例如 a != 1,转化为 a < 1 AND a > 1。
大量数据使用批量分块插入数据
其中一个影响因素是锁。一个事务插入已知数量的多条数据,只需获取一次锁。
使用覆盖索引
使用索引就能获取想要的值,不需要从数据表中读。
用于辅助索引。
因为索引的执行顺序是:
尽量不要在 select 字段多的时候使用 Distinct
批量删除数据要谨慎
批量删除会加锁
批量删除过程要写 undo 日志,一旦回滚,需要更多时间
避免数据类型隐式转换
隐式转换会使索引失效
标签:内置函数 分离 冲突 而不是 模块 信息 极限 git 失效
原文地址:https://www.cnblogs.com/schaepher/p/12846028.html