Category Archives: Linux

about linux

关于php mysql长连接、连接池的一些探索

作者: dplord, 访问量 5255





php连接mysql的方式,用的多的是mysql扩展、mysqli扩展、pdo_mysql扩展,是官方提供的。php的运行机制是页面执行完会释放所有该php进程中的所有资源的,如果有多个并发访问本地的测试页面 http://127.0.0.1/1.php 根据php跟web服务器的不同,会开相应的线程或者进程去处理该请求,请求完了会释放结果的。也就是php无法从语言层面从页面到页面之间传递一些数据,但是mysql_pconnect跟pdo中的ATTR, 设置array(PDO::ATTR_PERSISTENT => true)如下是可以实现长连接的。

$conn = new PDO($dsn, DB_USER, DB_PASSWORD,
    array(PDO::ATTR_PERSISTENT => true)
);

长连接的作用我觉得是在高负载的情况下,通过复用长连接,减少了每个页面的建立数据库连接的时间,而这个建立mysql connection的时间,在我的机器上

  • 在数据库connnections < 10的情况下 , mysql pdo 建立connection time 为0.003ms, mysqli建立connection time为0.14ms
  • 在数据库connection接近满的时候,mysql pdo建立connection time为0.13ms, mysqli建立connection time为0.13ms

以上样本都是在大概估测时间,时间太小不好估计。其实建立连接的时间并不长,那这样为什么需要mysql长连接、连接池这样的东西呢。那是在高负载下,比如server单机可以接受的mysql并发在200左右,web server的单机并发在700左右,那么当大批量500并发连接压过来的时候, web server没到满负荷, mysql提前到了满负荷,就会导致所有页面无法响应、或者已经建立好数据库连接的页面执行很慢。

php中的mysql长连接由于php的运行方式有多种,因而长连接实现也有多种。需要web服务器支持才可以实现长连接,因为php是没有进程池跟连接池这种概念的,绝大多数情况下php应用本身不是一个应用服务器(后起之秀swoole, 是一个优秀的php应用服务器,不过是在c层面做的)。因而php的长连接其实是搭载apache这样的带有mpm模块的webserver, linux 下apache会维护一个进程池,开启了apache mpm功能之后,apache会默认维持一个进程池,mysql长连接之后的连接,并没有作为socet连接关闭,而是作为一个不释放的东西,放进了进程池/线程池里面去。等需要连接的时,apache从它维护的进程池/线程池里面取出mysql  socket connnection, 然后就可以复用此连接了。

这里测试一下,首先本机环境是archlinux , 后文所用mysql httpd php都是自己编译的源代码,都在/home/dengpan/opt目录。httpd的mpm模型这里采用的是worker, httpd的mpm(apache用于并行方面功能的,俗称多路处理模块)其实有perfork、worker、event三种。mpm的好处是让apache随时有些备用的spare或者空闲的子进程(服务器线程池),随时等待新过来的请求,这样客户端不需要在请求服务之前等待子进程的产生。

使用什么mpm,需要单独指定编译进去apache里面去,比如编译work mpm到apache里面去,比如我的最简化httpd的编译参数是

./configure \
--with-apr=/home/dengpan/opt/apr-1.5.2 \
--with-apr-util=/home/dengpan/opt/apr-util-1.5.4 \
--prefix=/home/dengpan/opt/httpd-2.4.16 \
--with-mpm=worker

查看httpd加载的模块,

wp_1

看到worker.c 已经编译过去了,

mpm的配置参数为

<IfModule mpm_worker_module>
    StartServers             15
    MinSpareThreads         75
    MaxSpareThreads        250
    ThreadsPerChild         10
    MaxRequestWorkers      400
    MaxConnectionsPerChild   0
</IfModule>

启动apache用pstree看到 |-httpd—15*[httpd—11*[{httpd}]],说明起了15个server进程,每个server起了10个子线程。整个mpm要维持的最小的闲置线程数量在75,最大的闲置线程在250。满载的最大的工作线程在400个。下面准备一个shell脚本,每1秒输出下当前mysql的active连接数量, 查看mysql current连接数我用的较多的有2个方法

  • 进mysql shell, 执行SHOW STATUS WHERE `variable_name` = ‘Threads_connected'; 不过这个方法得mysql shell进的去才对,当connections很多的时候,mysql shell进不去也就无法查询了
  • shell直接查询,  find /proc/`pidof mysqld`/fd/ -follow -type s | wc -l , 需要root权限,好处是即使mysql因为too many connections无法进入shell的时候还是可以连接进去。

这里用方法2,因为后面回到机器的mysql满载负荷的。写一个shell如下:

#!/bin/bash
while(true)
do
    find /proc/`pidof mysqld`/fd/ -follow -type s | wc -l
	sleep 1
done

后面执行该shell不断的输出当前连接数,测试可得

  1. cli下执行php,长连接无效,cli下脚本一退出,连接即释放
  2. apche+mod_php不开启mpm模块的话,无论mysql mysql_pconnect、pdo_mysql长连接, 页面访问完毕, mysql连接即释放。
  3. apche+mod_php开启mpm模块(worker模式)的话,无论mysql mysql_pconnect、pdo_mysql长连接, 页面访问完毕, mysql连接+1,直到达到最大的mysql连接数,不在增加,但是访问页面还是可以复用连接查询到相应数据。
  4. nginx+php-fpm下mysql长连接基本无效果。

apache之所以能够复用mysql连接,说明apache肯定为mysql自己实现了一些功能函数、模块,否则不可能把一个未知类型的socket指针存下来的。用ldd查看,

➜  mysql_persist  ldd /home/dengpan/opt/httpd-2.4.16/bin/httpd
        linux-vdso.so.1 (0x00007ffffcbde000)
        libpcre.so.1 => /usr/lib/libpcre.so.1 (0x00007f8e8d17c000)
        libaprutil-1.so.0 => /home/dengpan/opt/apr-util-1.5.4/lib/libaprutil-1.so.0 (0x00007f8e8cf57000)
        libexpat.so.1 => /usr/lib/libexpat.so.1 (0x00007f8e8cd2d000)
        libapr-1.so.0 => /home/dengpan/opt/apr-1.5.2/lib/libapr-1.so.0 (0x00007f8e8cafb000)
        libuuid.so.1 => /usr/lib/libuuid.so.1 (0x00007f8e8c8f6000)
        librt.so.1 => /usr/lib/librt.so.1 (0x00007f8e8c6ee000)
        libcrypt.so.1 => /usr/lib/libcrypt.so.1 (0x00007f8e8c4b6000)
        libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f8e8c299000)
        libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f8e8c095000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007f8e8bcf3000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f8e8d3ec000)

可以猜测出/home/dengpan/opt/apr-util-1.5.4/lib/libaprutil-1.so.0跟/home/dengpan/opt/apr-1.5.2/lib/libapr-1.so.0应实现了跟mysql相关的代码段。由于我是本地编译的,很方便找到函数入口,/home/dengpan/github/apache-httpd/apr-util-1.5.4/dbd/apr_dbd_mysql.c这个文件,其实是apache的mod_dbd对常见的数据库都做了长连接支持。而nginx跟php-fpm的关系并不像php跟apache那样,所以nginx+php-fpm无法实现对应的长连接。大概是php-fpm并没有做mysql的进程、线程池。 Continue reading

macbook pro安装archlinux + mac os双系统

作者: dplord, 访问量 2083





入职时候公司发了一个macbook pro 15寸的机器,其实要不是公司发的我是很不喜欢apple系列的。就把我以前上学时候用的lenovo Y470上的archlinux想原封不动迁移过来。很多人说mac跟linux差距不大, 其实差距大太多了。mac在对command line友好上也就仅仅比windows好一点,加上homebrew还是不能符合我的要求。而mac os惊艳的图形界面、一系列apple服务、软件,我是用不上的。

开始我的做法打算
在我的os x yosemite 10.10里面通过mac自带的磁盘工具, 分一个区,我的硬盘是256G SSD, 本想给mac分区压缩出150G 出来给我迁移archlinux。本来说直接要删除mac的,但我一个对我很重要的一个朋友,她用mac机器,偶尔会问我一些关于电脑的问题,前不久还问我mac下代理上网的问题, 要是手头没机器,我怕是不好回答或者截图一一详细说明。

然后我想出的做法是

  1. 先在OS X里面分150G分区
  2. 刻录一个ubuntu启动U盘
  3. 用ubuntu启动盘进入我原来archlinux的电脑,用tar打包我原来整个archlinux分区到我的2T移动硬盘里面为一个arch-whole.tar 文件。
  4. 用ubuntu启动盘插入mac, 开机按option进入选择项,手动启动ubuntu, 安装ubuntu到mac的150G分区, grub安装在当前分区/dev/sda3
  5. 再次用ubuntu启动盘插入mac进入”try ubuntu”模式在shell下,删除已经安装的ubuntu所有文件,解压archlinux的arch-whole.tar文件到/dev/sda3
  6. grub页面,手动用kernel指定vmlinuz引导进archlinux, 在archlinux里面修复grub

其实这样是可行的,但是我的OS X,分磁盘的时候, 由于我的笔记本是公司2015-07-10发的新的15寸mbp分区的时候, 我是按照标准mac磁盘工具分区的,结果分区失败,无法急救,导致系统崩溃了。

后面就需要我自己下载一个mac镜像了,由于我的本子是2015-07-10的,搭载的系统比较新,所以我只能在最新的mac下下载最新的镜像刻录成安装U盘,才能装进去,不然的话,如果装旧于我机器的系统,会显示一个大大的圆圈+禁止斜杠,像这样:

1-1

其实也可以网络安装的,但是鉴于国内的网络,动辄几十小时或者100+小时的,中途只要出现问题就要重走一边,而且动不动报 apple.com/support -4403f  或者 apple.com/support -2203f 错误的,我是不会用这种方式的。

下载镜像的时候,是先离线到百度云,然后在我的服务器上百度云下载,axel -n 10 “百度云mac os下载地址”  -o 2.dmg 下载,大概2M/s的速度,下载了50min,服务器sha1sum得到sha1校验码为47c7d9c1c510b2cb74bae4c560c2553bcb12897f, 然后我在服务器用

7za  a 2.dmg.7z -v1800m -mx0 2.dmg

分卷压缩为3个文件, 其中-mx0指定只存储不压缩,等于文件拷贝把。 然后在我的pc 、我的macbook、我的nexus 6手机分别下载2.dmg.7z.001、2.dmg.7z.002、2.dmg.7z.003, 这样下载比较快,下载完了之后文件拷贝到一起,解压即可得到2.dmg, 本地检验校验码为

47c7d9c1c510b2cb74bae4c560c2553bcb12897f , 文件未损坏。开始刻盘装了。
先准备一个 已经格式化为mac os扩展日志式、GUID分区表的8G的U盘。

 

然后Mac下先挂载2.dmg

cd /Volumes/{2.dmg所在的盘符}

sudo /Volumes/{2.dmg所在的盘符}/Install\ OS\ X\ Yosemite.app/Contents/Resources/createinstallmedia – -volume /Volumes/{你的8G U盘的盘符} – -applicationpath /Volumes/{2.dmg所在的盘符}/Install\ OS\ X\ Yosemite.app – -nointeraction

大概20min,不报错的话,就刻录好了。用刻录好的U盘mac安装盘,开机option键,安装mac,安装过程跟window安装类似,很简单。

安装好了进mac, 用自带的磁盘工具,我是划分150G分区,格式化为exFat给我装linux的。我这个分区是/dev/sda4。

用我的2T wd的移动硬盘。打包我的整个pc上的用了一年的archlinux, 打包为一个tar包,打包过程在ubuntu live cd 进去打包,/dev /tmp /proc 等等不要打包。打包为arch-whole.tar

进ubuntu live cd, 安装ubuntu 15.04 到 /dev/sda4,grub 安装在/dev/sda4 上面。

然后装好了再进ubuntu live cd模式,挂载/dev/sda4,  删除/dev/sda4里面的全部东西。把我的arch-whole.tar全部解压到该盘。最后进入系统。在grub菜单里面,按e编辑grub,把set root=(hd1,msdos6) 修改为set root=(hd1,gpt4) , 因为mac是gpt 格式的。其他的也做对应的修改。最后大概改成如下的样子。

2-1

最后按F10引导进archlinux, 在arch下,grub-mkconfig -o /boot/grub/grub.cfg更新grub就好了。后面进入系统,修改下/etc/fastab  等等文件就好了。整个archlinux 原封不动的被我挪过来了。背光键盘、亮度调节、触摸板、网卡等等都支持良好。放几张图炸一炸跟我一样的inux死忠。

16G内存一般只用4G以下, CPU使用一般5%不到,编译速度非常快。

4722bd15bd3f62c7e2862c67e3ad286a

分辨率在1920*1200 其实可以调到2880*1800的,不过我不喜欢。

3-1

大屏看代码还是很爽很爽,加上mac的电池,带出去玩儿一天也不怕了。

23d35f87ef37a654542d2edc6be63758

 

对了要进mac系统的话,开机按option选择mac磁盘即可了。

 

linux编译ATI显卡驱动

作者: dplord, 访问量 939





事情起于今天班上一个女生zcm问我她要做毕设, 老师让装linux, 自己装ubuntu12.04 32bit 有问题, 让我帮看看, 作为linux死忠又是大学同班同学我就答应帮她把ubuntu12.04 32bit搞好(难得有女生有兴趣学习linux啊, 确实是比较少见的)。

我拿过来一看, 她的电脑是Acer的, 当时按照她的描述:

自己在学校镜像站下载了ubuntu12.04镜像, 安装完了就进去系统, 然后update了一下, 装了 build-essential 跟  xorg-dev 、多媒体开发库SDL 、ffmpeg等要用工具后,重启就进不去了, 表现为在ubuntu logo页面一半天进不去

我拿过来一看, 当时报了一个错误如下:

[drm:r600_uvd_init] *ERROR* UVD not responding, trying to reset the VCPU!!!
[drm:evergreen_startup] *ERROR* radeon: error initializing UVD (-1).

看到radeon 就是AMD显卡问题。

zcm电脑较新是Acer的, 显卡信息如下

2015-01-07 23:47:38的屏幕截图

集显是APU上附带的 Radeon  HD 6520G, 其实这个集显(其实APU上的不叫集显, 不过作用可类比intel CPU上的集显) 还是很强的, 比intel i3集显强多了, 比intel i5的集显只强不弱, 相当于一个入门独显的级别。

独显是  AMD Radeon HD 6400M Series 。

关于AMD 显卡驱动,  其实Askubuntu 已经有人发问了, http://askubuntu.com/questions/434521/drmr600-uvd-init-error-uvd-not-responding-trying-to-reset-the-vcpu

这里我打算给她重做一个ubuntu12.04 32bit的, 下载好刻U盘后, 安装的时候诡异的时候到了, 一直卡在安装页面不动

后面没办法, 在安装的时候需要进入文本模式, F6选择  nomodeset 模式, 再安装, 但是这样安装好了。

安装好之后, 默认进入页面之后, 卡在登陆页面不动根本无法键盘输入。后面在grub启动时,按E在grub引导菜单,  找到 quiet splash 字样,在后面添加 nomodeset , 这样会引导进去一个1024*768 的低分辨率的页面, 有这么强集显跟独显的只能用渣画质的 1024*768 的,简直不能忍, 我决定多费点时间帮她编译一个A卡驱动。之前我大一给我家台式机(HP-GT2070CX , 显卡ATI Radeon HD 4550 也是A卡), 安装过一次A卡驱动, 一下子在我的家庭21寸台式机上有了 1440*900  的分辨率, 配合Opensuse的字体渲染, 写代码水论坛看视频超爽。

其实关于显卡的linux支持现状, 其实目前已经很好了。显卡主要分A卡(AMD APU附带的显卡, ATI显卡) 跟 Nvidia 显卡 以及 Intel集显, 这3类。Intel集显不用说, 英特尔对Linux的支持力度相当大, linux内核提交代码的前几就有intel, 一般的笔记本电脑都是Intel i3、i5、i7 系列CPU, 都自带一个Intel集显, 这些电脑安装上linux基本没任何问题的, 默认就是全分辨率很方便的。Nvidia系列的显卡, 其实性能更出众, 游戏玩家必追啊, nvidia 由于要大力发展跑在android的GPU以及nvidia推出的CUDA GPU并行计算, 对linux 系列支持也是特别好, 对应型号都有相应驱动, 性能相当不错。Ps: 各大网格计算、云计算平台都广泛部署了对CUDA并行计算库的支持,我上次去我们学校东5楼闲逛, 看到了各大网格计算中心的部署工具中CUDA计算库简直标配, 附图如下:

这是ChinaGrid 教育网内, 几个一级节点跟二级节点分布。

打大红点的是一级主干节点,一共7个全国一级节点, 我们学校是华中地区的国家一级主干节点。

1-1

每个节点配备的软件都大致类似 ,GPU计算资源就是其中一个重要指标, 大规模用到了CUDA

1

以西北地区主干节点西安交大为例, 打红框的是该节点配备的资源大小与种类,有兴趣可以自己去玩玩这些软件。

扯歪了, 说完N卡的支持已经相当好了。再看A卡的支持, 其实AMD对linux近些年支持很不错, 各种 “AMD Linux催化剂驱动” 连续不断的紧急释出, 但是貌似由于时间、稳定性、协议之类的, 通用linux发行版没有把这些驱动给包含进去,需要自己手动编译。

去, AMD官网下载一个  amd-catalyst-omega-14.12-linux-run-installers.zip  的文件,

这个文件不能在vps上快速下载, 原因是限制了  Referer 跟  header

想命令行下下载amd驱动的, 可以写一个shell, 如下:

curl \
-H "Referer: http://support.amd.com/zh-cn/download/desktop?os=Linux+x86"  \
-H "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0
Accept: text/css,*/*;q=0.1" \
-H "Cookie: c_sccva=1420636121000%2CNA; s_fid=76ECADB0C01BD313-32D52C9175E1EF0A; s_cc=true; s_vi=[CS]v1|2A5697F3051D3FA3-4000010300002A71[CE]; fsr.s=%7B%22v2%22%3A-2%2C%22v1%22%3A-2%2C%22rid%22%3A%22d036702-53157432-4508-58ac-e4bc8%22%2C%22to%22%3A3%2C%22c%22%3A%22http%3A%2F%2Fsupport.amd.com%2Fzh-cn%2Fdownload%2Fdesktop%22%2C%22pv%22%3A1%2C%22lc%22%3A%7B%22d0%22%3A%7B%22v%22%3A1%2C%22s%22%3Afalse%7D%7D%2C%22cd%22%3A0%2C%22f%22%3A1420636735766%7D; com.silverpop.iMAWebCookie=1e589c02-c5a6-5556-d505-ac20ee930564; com.silverpop.iMA.session=8cc12ac6-6482-e51b-848a-c6a1bed35029; com.silverpop.iMA.page_visit=-1534868343,"  \
http://www2.ati.com/drivers/linux/amd-catalyst-omega-14.12-linux-run-installers.zip -o 1.zip 

执行这个shell即可下载了。

下载完了, 其实最好在 grub 添加参数进入 nomoset模式下安装, 以免现在的驱动影响新驱动的安装导致不成功。

这点A卡做的很好 , A卡可以在图形模式下安装, N 卡驱动只能关闭kdm 或者 gdm 在文本模式下安装, 而且安装N卡驱动需要你编译一次自己的内核, 这样才能把驱动模块安装到对应内核去, 更新内核的话, N卡驱动要重新安装的。

进入 nomodeset开始安装

1 先装依赖库

sudo apt-get install build-essential cdbs dh-make dkms execstack dh-modaliases fakeroot libqtgui4 debhelper debconf libstdc++6 dkms libqtgui4 libelfg0 linux-headers-generic

2 卸载可能存在的旧的A卡驱动

sudo apt-get remove --purge fglrx*

 

 3 解压缩执行下载的 amd-catalyst-omega-14.12-linux-run-installers.zip 的.run 安装文件

chmod a+x amd-driver-installer-14.501.1003-x86.x86_64.run 
./amd-driver-installer-14.501.1003-x86.x86_64.run  --buildpkg Ubuntu/precise  

其中:Ubuntu/precise 是 ubuntu12.04 代号, 这里代号要小写,每个版本的代号可以用  lsb_release -a 查询的。

此步编译deb过程也可以在图形化进行, 看个人喜好。

4 安装编译好的deb文件

sudo dpkg -i fglrx*.deb

 5 安装完,  还有一步初始化操作

sudo aticonfig --initial

重启后就好了, 部分电脑也许调整的Xorg.conf 参数不对, 需要自己手动去改一下。

这次的 amd-driver-installer-14.501.1003-x86.x86_64.run  驱动比以前稳定好多, 运行良好, 以前我给我家台式机(HP-G2070CX)装A卡驱动的时候, 当时版本还是一个beta版本, 不是很稳定, 每运行几个小时甚至30分钟就会崩一次, 现在进步太大了, 期待A 卡、N卡一如既往的给力啊。