服务器配置优化、系统参数调整、Linux 系统内核参数优化
vim /etc/sysctl.conf
net.ipv4.ip_local_port_range = 1024 65535 # 用户端口范围
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_fin_timeout = 30
fs.file-max=65535 # 系统最大文件句柄,控制的是能打开文件最大数量
数据库参数针对整个实例进行了优化
thread_concurrency #并发线程数量个数
sort_buffer_size #排序缓存
read_buffer_size #顺序读取缓存
read_rnd_buffer_size #随机读取缓存
key_buffer_size #索引缓存
thread_cache_size #线程缓存(1G—>8, 2G—>16, 3G—>32, >3G—>64)
连接层(基础优化)。
设置合理的连接客户和连接方式
max_connections #最大连接数,看交易笔数设置
max_connect_errors #最大错误连接数,能大则大
connect_timeout #连接超时
max_user_connections #最大用户连接数
skip-name-resolve #跳过域名解析
wait_timeout #等待超时
back_log #可以在堆栈中的连接数量
SQL 层(基础优化)。
:查询缓存
OLAP 类型的数据库,您需要专注于增加此内存缓存
但是,它通常不会超过 GB
对于经常修改的数据,缓存将立即失效。
我们可以使用内存数据库 (redis) 来替换其功能。
存储引擎层
基本优化参数
default-storage-engine
innodb_buffer_pool_size # 没有固定大小,50%测试值,看看情况再微调。但是尽量设置不要超过物理内存70% innodb_file_per_table=(1,0)
innodb_flush_log_at_trx_commit=(0,1,2) #1是最安全的,0是性能最高,2折中
binlog_sync
Innodb_flush_method=(O_DIRECT, fdatasync)
innodb_log_buffer_size #100M以下
innodb_log_file_size #100M 以下
innodb_log_files_in_group #5个成员以下,一般2-3个够用(iblogfile0-N)
innodb_max_dirty_pages_pct #达到百分之75的时候刷写 内存脏页到磁盘。log_bin
max_binlog_cache_size #可以不设置
max_binlog_size #可以不设置
innodb_additional_mem_pool_size #小于2G内存的机器,推荐值是20M。32G内存以上100M
一些大数据操作直接使用 limit start, count 语句
当起始页较小时,查询不存在性能问题,并且随着起始记录的增加,时间会增加
发现
1) limit 语句的查询时间与起始记录的位置成正比
2) MySQL 的 limit 语句很方便,但不适合记录很多的表
一种针对极限分页问题的性能优化方法
利用表的叠加索引来加速分页查询
我们都知道,如果使用索引查询的语句只包含该索引列(覆盖索引),那么查询将非常快。
因为有使用索引搜索的优化算法,而且数据在查询索引上,所以不需要查找相关的数据地址,节省了大量的时间。此外,Mysql 还有一个相关的索引缓存,在并发性高的时候用得比较好。
id 字段是主键,它自然包含默认的主键索引。
覆盖索引
如果索引包含(或覆盖)需要查询的所有字段的值,则称为“覆盖索引”。也就是说,您只需扫描索引而不返回表。
覆盖索引的优点
1. 索引条目通常比数据行的大小小很多,如果只需要读取索引,MySQL 会大大减少数据访问量。
2. 由于索引按列值的顺序存储,因此 IO 密集型范围查找的 IO 比从磁盘随机读取每一行数据要少得多。
3. 有些存储引擎只在内存中缓存索引,数据依赖操作系统进行缓存,因此需要系统调用才能访问数据
4. 聚集索引、 索引对 table 特别有用。
覆盖索引必须存储索引列的值,而哈希索引、空间索引和全文索引不存储索引列的值,因此 mysql 只能使用 B 树索引来做覆盖索引。
例子
:
select id from product limit 866613, 20
SELECT * FROM product WHERE ID > =(select id from product limit 866613, 1) limit 20
SELECT * FROM product a JOIN (select id from product limit 866613, 20) b ON a.ID = b.id
导出数百万数据
一。对于数据超过 65535 行的问题,很自然地会考虑将整个数据分成块,利用 excel 的多页功能,将超出 65535 行的数据写入下一个页,即通过多页的方式,突破最大 65535 行数据的限制, 具体方法是单独做一个链接,使用 JSP 导出,在 JSP 上通过程序判断报表行数,超过 65535 行后写入 SHEET。这解决了问题
二。在生成和导出这样的大数据报表时,会占用大量的内存,尤其是在使用的情况下,而且 JVM 最多只能支持 2G 内存,并且会出现内存溢出的情况。此时的内存开销主要有两个方面,一个是生成报表的开销,另一个是生成报表后编写 EXCEL 的开销。由于 JVM 的 GC 机制无法强制回收,因此我们将改变
执行此操作
设置报表的开始行和结束行参数,在 API 的报表生成过程中逐步计算报表,例如一个 行数据的报表,在生成过程中,起跑线和结束行可以执行 4-5 次。这样,减少了报表生成的内存占用,如果在后面的报表生成过程中发现内存不足,可以自动启动 JVM 的 GC 机制,回收上一个报表的缓存
导出 EXCEL 的过程是在报告的每个部分生成后立即进行,如果将多个工作表页面更改为多个 EXCEL,即在逐步生成报告的同时逐步生成 EXCEL,则通过 POI 包生成 EXCEL 的内存消耗也会减少。通过
如果后面的 EXCEL 生成所需的内存不足,可以有效地回收上一代 EXCEL 占用的内存
然后使用 FILE 操作,根据 AND 登录时间,为每个客户端的导出请求生成一个唯一的临时目录,用于放置生成的多个 EXCEL,然后调用系统控制台将多个 EXCEL 打包为 RAR
或者 JAR 模式,最终将 RAR 包或 JAR 包反馈给用户,响应客户请求后,再次调用控制台删除临时目录。
分割和生成有效地减少了从生成结果到生成 EXCEL 的报表内存开销。其次,通过使用压缩包,大大减小了响应用户的生成文件的大小,减少了多用户合并
访问时从服务器下载文件的负担,有效减少了多用户导出和下载时服务器端的流量,从而进一步减轻了服务器的负载
PHP 相关 CGI、PHP-FPM 不同 CGI
CGI 是一个公共网关接口,它的作用是帮助服务器与语言进行通信,这里是 nginx 和 php 来通信的,因为 nginx 和 php 语言不懂,所以它需要一个通信转换过程,而 CGI 就是这种通信的协议。
收到浏览器传递的数据后,如果请求是不需要动态处理的静态页面或图片,会直接根据请求的 URL 找到它的位置并返回给浏览器,不需要 PHP 参与,但如果是动态页面请求, 此时 NGINX 必须与 PHP 通信,然后就需要使用 CGI 协议将请求数据转换成 PHP 可以理解的信息,然后 PHP 从这些信息返回的信息也通过 CGI 协议转换成 NGINX 可以理解的信息,最后 NGINX 接收到这些信息并返回给浏览器。
快速 CGI
这
传统的 CGI 协议每次提出连接请求都会打开一个进程进行处理,处理后该进程会关闭,所以下次连接时,必须再次打开一个进程进行处理,所以有多少连接就有多少个 CGI 进程,这就是为什么传统 CGI 会出现慢的原因, 因此,太多的进程会消耗资源和内存。
Fast-CGI 不会在处理完每个请求后终止进程,而是保留该进程,以便它可以一次处理多个请求。这样就无需每次都再次分叉进程,从而大大提高了效率。
php-cgi 格式
PHP-CGI 是 PHP 提供给 Web Serve 的 CGI 协议接口程序,即 HTTP 前端服务器,当每个来自 HTTP 前端服务器的请求都会打开一个 PHP-CGI 进程来处理,而打开 PHP-CGI 的过程会首先使运行环境的配置、数据结构和初始化过载,如果 PHP 配置更新, 那么 PHP-CGI 需要重启才能生效,比如就是这种情况。
php-fpm
PHP-FPM 是 PHP 提供给 Web Serve 的协议接口,Web Serve 是一个 HTTP 前端服务器,它不像 PHP-CGI 那样为每个连接重新打开一个进程,并在处理完请求后关闭该进程,而是允许一个进程处理多个连接,而不是立即关闭该进程,然后处理下一个连接。可以说是 php-cgi 的虚拟机管理程序,是对 php-cgi 的改进。
php-fpm 会打开多个 php-cgi 程序,而 php-fpm 驻留在内存中,每次 web serve 服务器发送连接过来时,php-fpm 都会将连接信息分配给以下子程序之一 php-cgi 进行处理,处理完后这个 php-cgi 不会关闭,而是继续等待下一个连接,这也是 fast-cgi 加速的原理, 但是因为 php-fpm 是多进程的,一个 php-cgi 基本会消耗 7-25M 的内存,所以如果连接太多,会导致内存消耗过多,造成一些问题,比如 nginx 中的 502 错误。
同时,php-fpm 还附带了一些其他功能:
比如平滑过渡配置变更,普通的 php-cgi 每次改配置后都需要重启来初始化新的配置,而 php-fpm 不需要,php-fpm 会给新的子程序 php-cgi 发送新的连接,此时新的配置被加载了,原来运行的 php-cgi 仍然使用原来的配置,这个连接之后的下一个连接会用新的配置初始化, 这是一个平稳的过渡。
参考链接:....
这
PHP5 和 PHP7 之间的区别
PHP 7.0 声称在性能方面是革命性的版本。面对 HHVM 引擎的压力,开发团队将底层 Zend 重写为 Zend 2。
低级内核解析
PHP7 中最重要的变化是 zval 不再单独从堆中分配内存,也不自行存储引用计数。需要 zval 指针的复杂类型(例如字符串、数组和对象)存储自己的引用计数。这将减少内存分配操作、间接指针使用和内存分配。在 PHP7 中,zval 变成了一个值指针,它要么保存原始值,要么是一个指向已保存原始值的指针。换句话说,当前的 zval 相当于 PHP5 的 zval。但是,与 zval 相比,直接存储 zval 可以节省指针取消引用,从而提高缓存友好性
参考链接:
为什么 PHP7 比 PHP5 好
1. 这
减少可变存储字节数,减少内存占用,提高可变运行速度
2. 改进数组结构,数组元素和哈希映射表分配在同一个内存中,减少了内存占用,提高了 CPU 缓存命中率
3. 改进了函数调用机制,通过优化参数传递的环节,减少了部分指令,提高了执行效率
安全
功能修改
() 不再支持 /e 修饰符,同时官方给了我们一个新的函数 k
() 已弃用,实际上它是通过执行 eval 来实现的。
mysql* 系列已从全体员工中移除,如果您想在 PHP7 上使用旧版本的 mysql* 系列功能,需要自己安装,官方不自带,现在官方推荐是 or 。
() 添加一个可选的白名单参数,该参数实际上是一个白名单,如果反向序列数据中的类名不在此白名单中,则会报错。
() 默认不是可执行代码
语法修改
不再更改内部数组指针
八进制字符的容错能力降低,在 PHP5 中,如果八进制字符包含无效数字,则无效数字将被静默编辑。在 php7 中,会触发解析错误。
十六进制字符串不再被视为数字
删除了 ASP 和 PHP 标签
将浮点数转换为整数时,如果浮点值太大而无法表示为整数,在 PHP5 版本中,转换将直接截断整数,而不会导致错误。在 PHP7 中,报告了一个错误。
整体
性能改进:PHP7 的速度是 PHP5.0 的两倍。
全面的 64 位支持。
许多过去被更改为 [Throw ] 的致命错误。
与 PHP 5.0 相比,PHP 7.0 删除了一些较旧的不受支持的 SAPI([服务器端] 应用程序编程端口)和扩展。
。PHP 7.0 在 PHP 5.0 的基础上增加了一个新的 null 拼接运算符。
PHP 7.0 在 PHP 5.0 的基础上增加了一个新的组合比较运算符。
PHP 7.0 是 PHP 5.0 的新增功能,为函数提供了返回类型声明。
PHP 7.0 在 PHP 5.0 的基础上增加了标量类型声明。
PHP 7.0 添加了一个比 PHP 5.0 新的匿名类。
多个进程同时读取和写入文件
PHP 支持进程,不支持多线程(这个先清楚),如果是针对文件操作,其实你只需要锁文件就解决了,不需要其他操作,PHP 的 flock 已经帮你搞定了。
使用 flock 在写入文件之前锁定文件,写入后解锁文件,这样多个线程可以同时读写一个文件,避免冲突。
过程
flock 参数说明:file ,指定要锁定或释放的打开文件,lock is 。指定要使用的锁定类型。block 是可选的。如果设置为 1 或 true,则在进行锁定时阻止其他进程。
要获得共享锁(请阅读程序)。
获取排他锁(编写的程序)。
释放锁,无论是共享锁还是独占锁
如果你不希望 flock() 在锁定时被堵塞
在 PHP 中,flock 似乎不是那么好用!在多并发的情况下,似乎资源经常被垄断,没有立即释放,或者根本没有释放,导致死锁,这会使服务器的 CPU 使用率非常高,有时甚至会完全杀死服务器。好的,那么在使用 flock 之前,您必须仔细考虑。
溶液
锁档时,设置超时时间,设置超时为 1ms,如果在时间内没有获得锁,则会重复获取,当然会直接获得文件操作权。如果已达到超时限制,则必须立即退出,放弃锁定并允许其他进程运行。
不使用 flock 功能,借用临时文件解决读写冲突问题
考虑需要更新到临时文件目录中的文件,将文件的上次修改时间保存到一个变量中,并为临时文件指定一个随机的、非重复的文件名。
临时文件更新完成后,请检查原始文件的最后更新时间是否与之前保存的时间相同。
如果上次修改时间相同,则修改后的临时文件将重命名为原始文件,需要清除文件状态,以确保文件状态同步更新。
但是,如果上次修改时间与上一次相同,则表示在此期间已经修改了原始文件,这时需要删除临时文件并返回 false,表示另一个进程正在处理该文件。
对操作的文件执行随机读取和写入,以降低并发的可能性。
前面我们需要定义一个随机空间,空间越大,并发的可能性就越小,这里假设随机读写空间是 [1-500],那么我们日志文件的分布是 log1~ 到 。每次用户访问时,数据都会随机写入 log1~ 之间的任意文件。同时有 2 个进程在记录,进程 A 可能是更新的 log32 文件,进程 B 可能是在记录?可能的更新是 。你知道,如果你希望进程 B 也执行 log32,概率基本上是 500 分之 1,大约为零。当我们需要分析访问日志时,我们只需要在分析之前合并日志即可。使用这种方法进行日志记录的好处之一是,进程操作不太可能排队,从而允许进程非常快速地完成每个操作。
将要操作的所有进程放入单个队列中。
队列中每个被排除的进程都相当于第一个具体的操作,所以第一次我们的服务只需要从队列中获取到具体操作项的等价物,如果这里还有大量的文件操作进程也没关系,就排到我们队列的后面就行了, 只要你愿意排队,排队多长时间都无所谓。
扫一扫在手机端查看
-
Tags : 器服务器w2255处理_PHP 面试服务器优化和大数据
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。