寻觅生命中的那一片浅草......

发布者 夜行人

PHP的master与worker进程关系的一点纠结

纠结的起点

同事发了一篇文档,里面提及

  1. FPM 的 master 进程接收到请求
  2. master 进程根据配置指派特定的 worker 进程进行请求处理,如果没有可用进程,返回错误,这也是我们配合 Nginx 遇到502错误比较多的原因。

全文请参考: Nginx 与 FPM 的工作机制

我曾经认为Nginx也是由master负责派发请求给worker,但同事那边马上发了篇文档出来打脸,文章提到master只负责管理worker,如重启,重新加载配置文件,并不会派发请求。祥见:nginx平台初探

纠结过程

为什么我会纠结呢?

  1. 上面提到的Nginx
  2. fpm一开始其实是一个第三方管理软件,类似spawn-cgi,说白了就是负责启动php-cgi进程的,那PHP官方把它整合进来作为官方的php-cgi管理工具后,会委以「派发请求」这样的重任吗?

早上和同事一起纠结了一下,纠结过程如下:

  1. strace对比master和worker的行为,同事把Nginx和fpm都设置成了1个worker进程观察,得出结论是不会经过fpm的master进程
strace -e network -p fpm_master_pid
strace -e network -p fpm_worker_pid
  1. 放狗,发现另外一种说法,见:关于fastcgi和php-fpm的疑惑,引用如下

master进程并不接收和分发请求,而是worker进程直接accpet请求后poll处理.

master进程不断调用epoll_wait和getsockopt是用来异步处理信号事件和定时器事件.

这里提一下,Nginx也类似,master进程并不处理请求,而是worker进程直接处理, 不过区别在于Nginx的worker进程是epoll异步处理请求,而PHP-FPM仍然是poll.

  1. 把master干掉,看请求是否可以正常处理,经实际测试,master干掉后,worker依然在,请求也可以正常处理。
kill -HUP fpm_master_pid

其他

  1. worker进程数量不够的时候,显然是manager启动了更多进程,这个时候是manager怎么知道的

答:PHP源码分析 – PHP-FPM运行模式详解,看起来就是满足下面的条件就会执行 fpm_children_make

1. idle < pm_min_spare_servers
2. running_children < pm_max_children
3. MIN(MIN(idle_spawn_rate, pm_min_spare_servers - idle), pm_max_children - running_children) > 0
  1. nginx中配置的fastcgi_pass默认是fastcgi的监听端口,这个配置的意义是什么?

答:浅谈多进程程序的进程控制和管理方式,主要看「多进程下的套接字」,这段文字解释了为什么多进程不需要派发,因为它socket是多进程共享的

纠结论

fpm的master并不承担派发请求的角色。

特别鸣谢纠结侠:郑导(C好厉害)

其他资料

清理Zabbix旧数据

问题

磁盘空间不够了,要删除一些历史数据,后面换T级别的硬盘吧

解决过程

备份

硬盘有价,数据无价,在开始删除前,请先做个完整备份,万一以后要查呢。

/usr/bin/pg_dump -U ${zabbix_user} ${zabbix_dbname} | bzip2 -c > zabbix_pgsql_backup_20170309.dump.bz2

统计各个表大小

登入PostgreSQL

PGPASSWORD=xxxx  /usr/bin/psql -U zabbix

统计大小

SELECT *, pg_size_pretty(total_bytes) AS total
    , pg_size_pretty(index_bytes) AS INDEX
    , pg_size_pretty(toast_bytes) AS toast
    , pg_size_pretty(table_bytes) AS TABLE
  FROM (
  SELECT *, total_bytes-index_bytes-COALESCE(toast_bytes,0) AS table_bytes FROM (
      SELECT c.oid,nspname AS table_schema, relname AS TABLE_NAME
              , c.reltuples AS row_estimate
              , pg_total_relation_size(c.oid) AS total_bytes
              , pg_indexes_size(c.oid) AS index_bytes
              , pg_total_relation_size(reltoastrelid) AS toast_bytes
          FROM pg_class c
          LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
          WHERE relkind = 'r'
  ) a
) a;

删除方法一

无论表有没有做分区,都可以使用此方法

执行下面的SQL

DELETE FROM history WHERE itemid NOT IN (SELECT itemid FROM items WHERE status='0');
DELETE FROM history_uint WHERE itemid NOT IN (SELECT itemid FROM items WHERE status='0');
DELETE FROM history_str WHERE itemid NOT IN (SELECT itemid FROM items WHERE status='0');
DELETE FROM history_text WHERE itemid NOT IN (SELECT itemid FROM items WHERE status='0');
DELETE FROM history_log WHERE itemid NOT IN (SELECT itemid FROM items WHERE status='0');
DELETE FROM trends WHERE itemid NOT IN (SELECT itemid FROM items WHERE status='0');
DELETE FROM trends_uint WHERE itemid NOT IN (SELECT itemid FROM items WHERE status='0');

删除后,手动执行下回收空间

# trends_uint为表名
VACUUM (VERBOSE,ANALYZE) trends_uint;

此法存在问题,就是删除时间比较长,容易引起锁表,并导致Zabbix无法使用

查询是否锁表

SELECT relation::regclass, * FROM pg_locks WHERE NOT GRANTED;

更多请参考:burner1024/zabbix-sql

删除方法二

此方法适用于表做了分区,我们采用删除分区的方式,特点是快,就好像删除文件一样快,我怀疑PostgreSQL是不是一个分区就存一个文件

# 显示Schema的搜索路径
SHOW search_path;

# 从上面的输出可以看出,默认没有partitions,我们加入,如果不加入,在drop table的时候,就会提示does not exist
SET search_path TO "$user",partitions,public;

# 可以drop了,CASCADE的作用是把关联的触发条件删除,这触发条件,其实就是什么数据应该插入此分区的,现在已经是2017了,自然不会有2015的数据需要插入,所以可以放心删除
drop table history_uint_2015_01_11 CASCADE;

此法真是快到没朋友,最后 ,简单粗暴,根据上面统计出的表大小结果,我们来批量生成SQL,此处删除2015年的

grep _2015_ zabbix_table_size.txt |awk -F\| '{print "drop table" $3 "CASCADE;"}'

其他参考资料:

从下面的参考资料可以看出,自动创建分区,连删除分区,都是自动的

zz:开启TCP BBR拥塞控制算法

网络加速,类似第三方软件:锐速(serverSpeeder)

而BBR则是内核级支持,由Google贡献的代码,详细请打开:开启TCP BBR拥塞控制算法

zz:InnoDB个性化备份

来自云栖:InnoDB个性化备份
主要看下面,在slave上执行 stop slave,等一会,就可以通过cp目录的方式备份,好犀利

MegaCli64导入Foreign配置

背景

Hadoop集群昨天新加机器 ,还在Rebalance,早上同事发现有个节点的2个硬盘无法写了,fdisk -l也看不到,第一感觉是硬盘坏了,想换硬盘,但硬盘是上周才买的,然后怀疑是raid卡数据线有问题,奈何机房找到的是另外一条不知道什么线,为了尽快恢复服务,就让机房重新插拔下硬盘,然后开机

BTW:每块盘做的是RAID0

开机后的处理

首先用fdisk看看能否看到硬盘,看不到,然后用MegaCli64看物理盘是否存在

通过以下命令看到物理硬盘是在的,但状态是Foreign

sudo /usr/local/bin/megasasctl  -PDList -aALL

Google一翻后,发现以下指令可以处理

执行状态检测命令:

sudo /usr/local/bin/megasasctl  -pdlist -aall |grep 'Firmware state'

输出,其中最后2个为raid有问题的盘

Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Unconfigured(good), Spun Up
Firmware state: Unconfigured(good), Spun Up

执行导入命令

sudo /usr/local/bin/megasasctl  -CfgForeign -Import -aall        

Foreign configuration is imported on controller 0.

Exit Code: 0x00

再次执行状态检测命令:

sudo /usr/local/bin/megasasctl  -pdlist -aall |grep 'Firmware state'

输出,正常了,因为是raid0,所以比较快

Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Online, Spun Up
Firmware state: Online, Spun Up

一点总结:

  1. 未必是硬盘坏了
  2. 硬盘线估计也没松
  3. 确认故障前,先不急着关机让机房检测,适当进行一些在线检测

参考资料

dell服务器硬盘的状态变成外来(foreign)命令行修复

2024年四月
« 5月    
1234567
891011121314
15161718192021
22232425262728
2930