PHP连接池实现的一种想法

虽然现在名义上是PHP开发,不过做这数据分析的事,平时工作大部分用的是JAVA。C语言出身,学的语言比较多,JAVA还算熟悉,不过之前一直都没用连接池。第一次遇到连接池是在学校的时候女朋友用连接池出现问题了,找我,我看了下觉得没必要,直接就删了。那时候用的是第三方扩展,感觉很麻烦,也没必要。工作后,面对上百T的数据,同时并发的大量数据库链接,才发现连接池的必要性。于是上周五自己封装了一套链接池。写完后,在想JAVA可以实现连接池,那么PHP呢?我们用PHP做WEB开发,他们是不常驻内存的,连接池要放在哪,又以何种方式去获取链接呢。然后看到了这一篇文章:http://blog.csdn.net/tangxy723/article/details/8607167

这篇文章是在PHP与数据库之间又构建了一个缓存系统,把大部分的数据都放入缓存系统中。这样一来大部分的访问都只需要链接缓存系统,仅有少部分还需要进入数据库。这篇文章给我些启发,既然PHP的速度足够快,那么导致数据库访问速度慢的原因在哪呢。我用java测试,发现直接用JDBC使用主键索引访问一个有700W条记录的表(由两个字段组成的联合主键,用主键中的字段进行分区,分了10个区)需要耗费的时间是380毫秒左右。而同一条SQL语句使用连接池的方式,只要70-80毫秒。这中间差了300毫秒,差在哪呢。连接池比起直接访问,只是连接池事先打开了链接,省去connection的过程,也就是说打开一条数据库链接需要消耗一次数据库访问近四分之三的时间。那么剩下的70-80毫秒,我们还有必要优化吗,我写了个demo测试了下,PHP直接从0加到700W要多久。demo如下

    public function test() {
        $st = $this->getMillisecond();
        $i = 0;
        while ($i < 7000000)
            $i ++;
        echo $this->getMillisecond() -$st;
        die;
    }

    private function getMillisecond() {
        list($t1, $t2) = explode(' ', microtime());
        return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
    }


我的几次的测试结果是:218 207 225 203 221。显然都是在200毫秒以上,因此我认为这块的时间没必要在优化了。随便一提同样的的代码,在java中只要1毫秒,PHP的计算性能还是差了很多。到此,我认为解决数据库访问速度慢的问题可以使用类似java连接池的方式解决,即先打开链接,然后任务。问题在于人家java能常驻内存,支持多线程,连接池只需要开一个线程维护,要用的时候找这个线程就可以直接获取到内存对象了。但PHP用于WEB,每一次请求的时候开始,请求结束的时候结束,不常驻内存,也没多线程可言。解决这个问题,我的想法是用先在服务器上开启一个PHP守护进程,这个守护进程打开并维护多个链接对象,起着连接池的作用,然后每一次数据库的访问都由这个守护进程发起,这是进程间通讯,具体使用管道还是网络都可以,只要把SQL语句传给守护进程,守护进程启动一个闲置的连接去执行这条SQL,并将放回结果以进程间通信的方式返回。写了个demo测试管道读取的速度:


    public function test() {
        $st = $this->getMillisecond();
        $file = file_get_contents(__DIR__."/test");
        echo $file."</br>";
        echo $this->getMillisecond() -$st;
        die;
    }

    private function getMillisecond() {
        list($t1, $t2) = explode(' ', microtime());
        return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
    }


上图了执行结果,test文件大小为3k。无论几次执行结果,消耗时间都为0。也就是说我们读取的时间可以忽略掉。然后再写一个demo进行写入,


    public function test() {
        $file = file_get_contents(__DIR__."/test");
        $st = $this->getMillisecond();
        file_put_contents(__DIR__."/test",$file,FILE_APPEND);
        echo $this->getMillisecond() -$st;
        die;
    }

    private function getMillisecond() {
        list($t1, $t2) = explode(' ', microtime());
        return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
    }


测试平均值为12。也就是说,整个过程我们我们可以节省的时间是300-12=288毫秒,速度上提升了很多。


最后,这只是个思考的笔记,一时的想法,现在没有时间具体实施。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值