hanfeng.name

I am a software engineer with interests in web applications.

负载计算方法及不同语言开发解决性能问题的思想等

前言

当项目复杂度和用户数提高的时候,我们常常会遇到以下问题:卡、 挂、 数据备份、 数据分析、 安全、 24小时在线、 多平台、 多端、 跨地域、 实时性强。

总结起来就是以下4个方面:

  1. 性能问题
  2. 交互问题
  3. 安全问题
  4. 可持续发展与维护

性能计算

不同语言开发解决性能问题的思想

  1. PHP -> 多进程

PHP通常是和Apache一起来工作,将PHP作为Apache的一个模块来使用,或者采用FastCGI方式通过FPM与web容器通信。我们的每一个用户的请求都将使用一个进程来处理用户请求。

  1. JAVA -> 多线程

单个进程中同时有多个函数在运行,我们就认为这个应用时多线程的。

  1. NodeJs -> 单进程单线程

Nignx 与 nodejs jetty 提升效率的方法相同。

都是 异步&非阻塞。

阻塞

Apache接收到用户的请求 -> 创建php进程处理请求 -> php通过Http协议解析获取用户提交数据 -> 进行数据过滤与加工 -> (接收用户上传的文件) -> (对图片缩放/给图片加水印) -> 将数据插入到数据库 -> 等待数据处理完成 -> 加载模板 -> 输出页面 -> 结束进程 -> 回收资源

PHP是单线程的,所以要等待用户上传文件、等待对图片处理、等待插入数据库的结果。一直在等待,所以耗时间。而nodejs是基于事件的编程、非阻塞,效率高。

高负载项目优化

IO Input/Output

  • 磁盘IO
  • 网络IO
  • 数据库IO

性能测试

  • php 系能测试
  • mysql读写性能测试
  • 文件 读写性能测试

测试工具

  • Apache ab
  • Apache JMeter

负载的计算方法

  • 网络连接最大并发数 B
  • 单次请求的处理时间 dt
  • 用户n秒请求一次
  • 发摩擦系数s : 一般 0.65
  • 负载 = B/dt * n

例子:

  • 网络连接最大并发数 B = 1000 次
  • 单次请求的处理时间 dt = 3秒
  • 用户30秒请求一次 n = 30秒
  • 发摩擦系数s : 一般 0.65
  • 每秒能处理的请求数 = 1000次 /3秒
  • 负载 = 每秒能处理的请求数 * 30秒 * 0.65 = 6500

总结:

  1. 负载 就是WEB服务能够支持的最大访问人数,不卡,不Down机。它取决于3点(最重要的):网络最大连接数、单次请求处理时间 和 用户多少秒请求一次。
  2. 对网络连接最大并发数 B 起决定性作用的依次是带宽、内存、CPU、操作系统。
  3. 减少单次处理请求时间,对程序员说很困难。
  4. 提高用户请求一次的时间是一个有效的办法,所以一个好的网页交互师很重要。比说增加验证码、提示框等。

集群:

在同一个项目,多台服务器一起工作

数据库优化原理

  1. 优化第一条:针对查询建索引。where条件要匹配索引,叫做命中索引。

问: 索引为什么会加速查询?

答:因为添加索引,会优化搜索算法,使用了二叉树、平衡二叉树、红黑树升级的算法。建立索引,查询速度会集合倍提高。 牺牲了写入数据的效率,换来了查询的速度。但因为我们大部分都是查询,写入的少。性能不会凭空产生

容器:内存中可以用来保存其他对象的对象,比如链表、数组、hashmap

资源:应用程序从内存意外的地方读取或写入数据的对象成为资源,比如网络,比如磁盘文件。涉及资源IO的程序通常速度都会比较慢。

结果集: 自己是个容器,从结果集获取数据的本质是一种资源,也是一个集合,不能有重复。(结果集是一个保存指向数据库资源指针的集合

当多个条件查询的时候,and条件表示左右两个条件搜索到的结果集做交集。 如果使用or连接两个条件,左右两个条件搜索的结果做并集。

selec … limit 0, 20;

遍历结果集,从数据库文件里面取。

select … where id = 1;

….

select …. where id = 20;

分页的作用:让每一次数据查询返回的结果集可控。

数据的查询一定要分页。

当写入大于查询的时候,要去索引,去掉只剩下一个id。

读写差异定制

数据库主从,主库没有索引,从库加索引。数据库的主从原理是根据主库的日志,把主库的bin log日志再从新执行一遍,这叫读写差异定制。

自建索引

如果是单个数据库。

建立索引越多-> 插入一条数据时间长->锁表时间长 -> 其他记录等待时间长 并发的时候, 堵车撞车几率就大。就容易让数据库挂掉。

不锁表,MySQL的连接数也会增加,满了。PHP连不上mYSQL, Nginx连不上mysql,会报502。索引越多越糟糕

user 基本表 user_index 保存搜索条件。

一台机器,专门用来保存数据。另一台数据用来保存索引。 或者一个库用来保存数据,另一个库来保存索引。

每天固定时间建立索引。

这叫做异步建索引

sphinx

爬数据库的爬虫,为我们的数据库建立索引。

能够大幅提升性能,对小说站,资讯站很有用。但是优缺点:不是实时索引。

redis索引

微博 把索引放到了redis里面,建立实时索引。

插入数据的时候,把索引写到redis里面。 查询数据,从redis里把满足用户的id查询出来。再查mysql数据库。 每一条索引都命中id,效率会特别高。

list可以保存索引,hash缓存对象,set用来交并集处理。所以,redis有建立索引和保存数据的作用。

redis:1.数据结构支持(消息队列) 2. 缓存 3. 索引(要存储到数据库)

 笛卡尔集

A B C 三个表

A表搜索10条记录找到1条,B表搜索到5条记录找到1条,C表搜索5条记录。

连表的话,会搜索100条记录。

根据业务逻辑做优化。

分表分库

  • 横向: 横切一刀, 表的数据被分成两部分。
  • 纵向: 刷刷两刀,一个表的字段减少。

优化最求:所有的事情可控。

小规模分表、大规模分库。

横向切表 tb_user

tb_usser0

tb_usser1

tb_usser2

tb_usser3

纵向且表,表重构

tb_user_login

tb_user_info

tb_user_account

多主多从。 多主一从。 互为主从。

MongDb

支持平行扩容和分片

高性能、高并发、海量扩容

js + mongodb: 效率高、速度快、并发高、数据扩容方便

Mysql主从配置

Comments