PHP 如何读取大文件( 1G 文本文件),并且正则匹配查找内容

2017-08-09 14:38:29 +08:00
 solaro

如题 现在实际业务项目中,目前只能想到用切割 并且参照了如下的文章,读取速度是挺快的,但是要怎么正则匹配出我想要的内容(说白了就是全文搜索) http://blog.csdn.net/jinxingfeng_cn/article/details/52042834

现在的业务需求是:尽量保证扫一遍 1G 文件得在 3 秒内响应。 preg_match_all。。。这个直接用到文件上,好卡好卡好卡

求大神给个思路或者实现方式

4792 次点击
所在节点    问与答
22 条回复
mhycy
2017-08-09 14:45:48 +08:00
1G 文件 3 秒内响应,假设文件为 1GB
不计算运算时间以及 IO 等待耗时,平均每秒读取速度 1024/3=341.333333333MB/S
首先需要一个 SSD。。。。
a591826944
2017-08-09 14:50:03 +08:00
1G 嘛。。也不算太大。。服务器内存怕啥。。拉到内存里面搞啊。
solaro
2017-08-09 14:50:31 +08:00
@mhycy。。。SSD 有了,硬盘不是问题,主要还是思路,难道真的要切割吗?
solaro
2017-08-09 14:50:56 +08:00
@a591826944 就是不能直接放到内存里面的。。。瞬间内存没了一个 G
a591826944
2017-08-09 14:54:54 +08:00
@solaro 你家服务器多大的啊? 一个 G 没多少啊。
a591826944
2017-08-09 14:55:43 +08:00
@solaro 我们连 docker 容器 都有 20 个 G 的内存。供后台跑数据。
gouchaoer
2017-08-09 15:07:27 +08:00
你的 php 程序是一个 php-fpm 还是 php-cli 呢,1G 的文本读进内存也就是个 1G 的 string 而已,如果是 php-cli 的话我认为内存不是问题,如果是 php-fpm 显然是不能读 1G 文本文件的
有 2 个方案,第一个就是用 yaconf 扩展把文本文件读入共享内存,这样 php-fpm 共享一个 string 副本,每次 get 配置的时候应该会得到一个共享内存的字符串(我不太确定会不会发生 string 复制,发生了复制的话这个办法就不行了: https://github.com/laruence/yaconf/blob/master/yaconf.c#L376,@sagaxu

第二个就开一个 php-cli 常驻内存专门接受请求

你这个正则是搜索敏感关键词的话,php 有对应的库: https://github.com/imaben/php-akm
gouchaoer
2017-08-09 15:09:19 +08:00
你应该把搜索 1G 文本需求细说一下,否则不知道怎么优化
zenxds
2017-08-09 15:11:09 +08:00
模式不复杂的化估计用 awk 就能搞定
solaro
2017-08-09 20:06:29 +08:00
@a591826944 VPS 就 2G 内存啊哥哥
solaro
2017-08-09 20:06:44 +08:00
@a591826944 你土豪,VPS 就 2G 内存
R18
2017-08-09 20:14:24 +08:00
@solaro #11 上报加内存啊,我们内存 60G
sagaxu
2017-08-09 23:52:38 +08:00
yaconf 是 zero copy 的,不会复制那个 string。但是一秒跑 300M 正则,未必做得到,因复杂度不同而异。
geelaw
2017-08-09 23:55:42 +08:00
对于固定的表达式把它编译成固定的代码就好了
msg7086
2017-08-10 04:13:13 +08:00
首先你对于正则的要求也没说清楚。如果正则本身就可能匹配超长内容的话,切割也是没用的。如果是小段匹配的话,找分隔符切割再匹配就好了。
baelish
2017-08-10 07:55:05 +08:00
可以调用 linux 的 grep 命令来解决。
sofs
2017-08-10 08:20:28 +08:00
1g,3 秒,除了提前放内存里,没其它方法
lianxiaoyi
2017-08-10 09:17:46 +08:00
楼上哥们说的没错。。。直接用 linux 命令 grep 吧 。。。。这也是支持正则的。。。。
nullen
2017-08-10 09:48:11 +08:00
看看能否讲一下具体的需求?可以考虑重新设计方案。
mrgeneral
2017-08-10 10:41:29 +08:00
记不记得有一招直接执行命令行的操作?

exec('grep ...')

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/381656

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX