2023年7月26日发(作者:)
PHP连接池实现的⼀种想法虽然现在名义上是PHP开发,不过做这数据分析的事,平时⼯作⼤部分⽤的是JAVA。C语⾔出⾝,学的语⾔⽐较多,JAVA还算熟悉,不过之前⼀直都没⽤连接池。第⼀次遇到连接池是在学校的时候⼥朋友⽤连接池出现问题了,找我,我看了下觉得没必要,直接就删了。那时候⽤的是第三⽅扩展,感觉很⿇烦,也没必要。⼯作后,⾯对上百T的数据,同时并发的⼤量数据库链接,才发现连接池的必要性。于是上周五⾃⼰封装了⼀套链接池。写完后,在想JAVA可以实现连接池,那么PHP呢?我们⽤PHP做WEB开发,他们是不常驻内存的,连接池要放在哪,⼜以何种⽅式去获取链接呢。然后看到了这⼀篇⽂章:这篇⽂章是在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.""; 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毫秒,速度上提升了很多。最后,这只是个思考的笔记,⼀时的想法,现在没有时间具体实施。
发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1690379383a340672.html
评论列表(0条)