王大力

用心去做好每一件事


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 公益404

记一次 excel 数据导入的性能优化

发表于 2018-08-02 |

需求交待

  1. 公司业务和肿瘤相关。目前相关的肿瘤类型共35种。
  2. 有 Excele 文件,大概5万条数据。有20列左右。 导入数据库。
  3. Excel中A列为肿瘤类型列,其值在35个肿瘤类别中。
    1. A 列值为『通用』值时,需要根据35个肿瘤类型,插入35条记录。
    2. A 列值为『其它』值时,则根据『B\C\D\E\F\G\E』列的值进行组合,查询与组合值相同的肿瘤类别,与肿瘤类型库取差集,根据差集肿瘤类型,填充数据,再插入数据库中。

第一回合:从入门到放弃

  1. 使用 Laravel 的 Exeel处理库,maatwebsite/excel ,很不幸运,最新版的 3.0 不支持读取,Fuck

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    2. 使用原始的Exel处理库,phpoffice/phpspreadsheet,php最强大的 excel 类库,没有之一。
    3. 读取 100 条 xlsx 文件的记录,需要2秒。1K数据,近2分钟。原始的5万条数据,我是没有耐性等它读完。再次Fuck~~~『ps: 这个测试过程很累,因为 Fuck 了的缘故吗』
    4. 学习过GoLang,那试试 GoLang的处理效果,使用 ```Luxurioust/excelize``` 5w条数据,大约需要20秒,还不错,非常理想。
    5. 但导入数据还有其它业务,毕竟项目组还是PHP项目组,怎么办呢...
    6. 试了试,用GoLang把数成导出成json,PHP解析这5w数据的 json ,秒级别解析,效果还可以。
    7. 导入原始数据啦,5w多条分批次插入,本机测试3分钟,服务器1分钟完成。还是可以接受的。

    > 第一回合结束,Go 编写 excel2json 程序, win\linux\mac各一个,cnv配置路径

    ### 第二回合:xlsx到cvs

    1. 找了一个 GoLang 的 ORM gohouse/gorose,尝试插入,2秒钟完成5w数据插入,Fuck

  2. 观察到其它同事处理上百万数据的 excel 文件,后缀都是 csv,那也来试试 csv 好了

  3. PHP和GOLang都内置了 csv的解析器,这一次PHP并没有输的那么难看,5秒内都能解析完成。那还用xlsx干毛线
  4. csv 的话,需要注意编码,用 Microsoft Excel 导出,貌似是 GBK编码。用 Macos的Number导出,貌似是UTF8。当然,我们需要的是UTF8
  5. 现在爽了,挺快的了。绝对时间了,PHP也能接受(30秒左右),但GO只需要2秒啊~~~

第三回合:拆数据

  1. 需求中,『通用』的情况,在导入原始数据时,稍加处理,一并插入即可。
  2. 『其它』就比较麻烦,因为需要按值查询,所以最初的想法就是导入后,二次处理。
  3. 大概思路就是一次找出所有其它,再对每一个其它进行一次查询,一次插入。算下来,有10k的其它,一共需要10k+1次查询,10k次插入
  4. 那就干吧,写完代码,跑起来,加了进度条,估算一次本机需要3小时才能完成…,,服务器上跑,也要跑1小时…要疯了
  5. 也想用Go去写这估逻辑,试试速度,但没有写完
  6. 慢,找到慢在哪里,尝试解决吧。
    1. 批量插入,收益甚微
    2. 增加一列,保留组合查询列的摘要,将直接查摘要。这一次速度有飞的提升
  7. 最后的测试数据,服务器上从头执行,100秒内 可以完成。

总结

从最开始可能需要1到2小时执行的程序,到最后100秒,效果还是符合要求的。总结关键点,欢迎讨论噢:

  1. excel处理,尽量选择 csv 文件
  2. 数据插入,一定要批量插入
  3. 查询,特别是组合查询,创建好索引,或者特定场合使用冗余列

php 检测代码执行时间

发表于 2018-07-16 |

某些时候对于执行时间较长的代码块,我们想知道哪块最耗时,耗了多少,可以使用如下方法,做个简单的探测:

完成小目标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* @开始时间
*/
function proStartTime() {
global $startTime;
$mtime1 = explode(" ", microtime());
$startTime = $mtime1[1] + $mtime1[0];
}

/**
* @检测点时间
*/
function proEndTime() {
global $startTime,$set;
$mtime2 = explode(" ", microtime());
$endtime = $mtime2[1] + $mtime2[0];
$totaltime = ($endtime - $startTime);
$totaltime = number_format($totaltime, 7);
echo "<br/>process time: ".$totaltime;
}

在需要的地方,插入

1
2
3
4
5
6
7
8
9
10
// 记时开始
proStartTime();
...
... // 你的代码
...
proEndTime();
...
... // 继续检测
...
proEndTime();

以上内容参考博客 花儿为何那样红

ps 本次检测主要是批量修改订单状态很慢,代码级别的优化,效果有限。后来针对数据字段做了索引,效订提升近百倍。

不足

这种检查测方式可以完成工作,但检查后代码还是移除,这些手工操作难免失误。

且无法从整体上去观察项目的代码运行效率。

完善:Xdebug

等改天使用完成补

在 PhpStorm 中使用 Xdebug

WebGrind 工具的使用

php 给 pdf 签名

发表于 2018-07-06 |

引子。说说我们公司吧,以二代测序技术和生物信息学为核心,从事肿瘤个体化精准诊疗和伴随诊断。粗暴一点来讲,卖报告的。报告以PDF文档为载体,纸质文件会加盖公章。

需求:使用证书给PDF签名,防止篡改

签名的这东西,在 https 标配化的今天,已经很普遍了。大概意思,比如我(王大力)发布一个文档,我用我的签名文件(即数字证书)给文档加一个签名,让阅读文档的人知道,哦,这个文档是大力的。一旦别人坏人修改了内容,则大力的签名即消息。因为别人是没有我的签名的,签名不能被模仿。

其中主要的技术环节,主要是有大型的机构纷发、核验签名证书。PDF 阅读软件对签名的检查和提示。最重要的是我必须保护好自己的签名,不能让坏人得到。否则,坏人就可以冒充我发布内容,而让我背锅…

阅读全文 »

Nginx 下载文件不完整

发表于 2018-07-03 |

通过 php readfile 输入一份文件,文件约 5.2MB 使用 wget 命令下载。
wget http://10.10.20.104:8084/api/h5/reports/file1
每一次得到的文件大小都不一样

1
2
3
4
5
6
#第一次
preview [ <=> ] 539.26K --.-KB/s in 0.002s
2018-07-03 11:12:45 (249 MB/s) - ‘preview’ saved [552206]
#再来一次
preview.1 [ <=> ] 791.23K --.-KB/s in 0.003s
2018-07-03 11:12:46 (281 MB/s) - ‘preview.1’ saved [810222]

发现每次开始下载,然后就结束了,中断了。第一感觉应该是文件长度没有返回,客户端不知道下多少。所以 php 代码补上。

1
header('Content-length:5498687');

再次执行 wget 下载,发现了有趣的现象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Connecting to 10.10.20.104:8084... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5498687 (5.2M) [application/pdf]
Saving to: ‘preview.7’

preview.7 10%[====> ] 539.39K --.-KB/s in 0.002s

2018-07-03 11:28:21 (303 MB/s) - Connection closed at byte 552340. Retrying.

--2018-07-03 11:28:22-- (try: 2) http://10.10.20.104:8084/api/h5/reports/17007/preview
Connecting to 10.10.20.104:8084... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5498687 (5.2M) [application/pdf]
Saving to: ‘preview.7’

preview.7 32%[=================> ] 1.73M --.-KB/s in 0.004s

2018-07-03 11:28:23 (415 MB/s) - Connection closed at byte 1809684. Retrying.

--2018-07-03 11:28:25-- (try: 3) http://10.10.20.104:8084/api/h5/reports/17007/preview
Connecting to 10.10.20.104:8084... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5498687 (5.2M) [application/pdf]
Saving to: ‘preview.7’

看到 wget 在循环断点下载。文件长度确实生效。但并没有达到预期。

此时使用 apache 做服务器,下载文件一气呵成,估计还是 nginx 的问题。

查看 nginx 的 error.log,发现大量的权限错误:

1
2
2018/07/03 11:25:39 [crit] 32747#0: *7 open() "/usr/local/var/run/nginx/fastcgi_temp/4/00/0000000004" failed (13: Permission denied) while reading upstream, client: 10.10.20.104, server: , request: "GET /api/h5/reports/17007/preview HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "10.10.20.104:8084"
2018/07/03 11:25:41 [crit] 32747#0: *9 open() "/usr/local/var/run/nginx/fastcgi_temp/5/00/0000000005" failed (13: Permission denied) while reading upstream, client: 10.10.20.104, server: , request: "GET /api/h5/reports/17007/preview HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "10.10.20.104:8084"

推测是文件比较大,需要缓冲,然后临时文件没有了写入权限产生的,改改式试吧。

1
sudo chmod -R 777 /usr/local/var/run/nginx/fastcgi_temp

果然,解决问题。

找了相关资料的一段描述:

nginx会使用fastcgi_buffer_size指定的大小的缓冲区用于缓存fastcgi流的内容。当大小超出此大小时会继续用fastcgi_buffers指定的数量和大小申请缓冲区。如果依然超出此大小,会将多出的内容写入临时文件。就导致了该问题。

问题解决了,面上的原因是权限错误,深层次,应该将 php-fpm 和 nginx 用户统一吧。

Hexo 添加 https 访问

发表于 2018-07-02 |

参考这哥们的博客 https://jaeger.itscoder.com/web/2017/08/30/github-page-https

我也使用了 netlify 的服务。 一步一步来,坑是在域名服务商配置那块,没有配好的时候, netlify 去测试地址,总是不通过。 有一项不通过,也可以继续去搞 https .

另外,强即 http 转 https ,netlify也有一个配置。

前后大概花了2个小时,看似简单,也需要一步一步去摸索啊。

我的域名配置参考:
dynoat

Hexo 初探 增加标签和分类页面

发表于 2018-07-02 | 分类于 hexo |

新的项目,安装了主题,修改了主题对应的配置文件 _config.yml,如下:

1
2
3
4
5
6
7
8
9
menu:
home: / || home
# about: /about/ || user
tags: /tags/ || tags
categories: /categories/ || th
archives: /archives/ || archive
#schedule: /schedule/ || calendar
#sitemap: /sitemap.xml || sitemap
commonweal: /404/ || heartbeat

很好,但前端点击 标签 或 分类时,出现404错误。这两个页面本来该自动出现的,但是没有。要我说这算是 hexo 的 bug。好在已经找到解决方案。

添加标签页

1
2
# hexo new page tags
# INFO Created: ~/Documents/hexo/source/tags/index.md

会创建 tags/index.md 文件,修改文件内容如下示例:

1
2
3
4
---
type: tags
date: 2018-06-28 18:23:15
---

关键在于 type ,hexo会自动计算标签和链接。

添加分类页

1
2
# hexo new page categories
# INFO Created: ~/Documents/hexo/source/categories/index.md

会创建 categories/index.md 文件,修改文件内容如下示例:

1
2
3
4
---
type: categories
date: 2018-06-28 18:23:15
---

关键在于 type ,hexo会自动计算分类的统计。

添加自定义菜单页

1
2
# hexo new page "guestbook"
# INFO Created: ~/Documents/hexo/source/guestbook/index.md

在主题的 _config.yml 文件中的 menu 中进行匹配

1
2
3
4
5
6
7
8
9
10
menu:
home: / || home
about: /about/ || user
tags: /tags/ || tags
categories: /categories/ || th
archives: /archives/ || archive
schedule: /schedule/ || calendar
sitemap: /sitemap.xml || sitemap
commonweal: /404/ || heartbeat
guestbook: /guestbook #自定义

关于 公益的404 的应用

菜单上的链接

人人其实都有一颗公益的心,只是有的做的多,有的人做的少

回到最开始的菜单配置,这是为你的博客添加了一个 “公益404”的菜单

1
2
3
menu
...
commonweal: /404/ || heartbeat

实际上该菜单指向一个普通页面

1
hexo new page 404

修改 source/404/index.md 内容如下:(支持 https 噢)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
title: 404
date: 2018-07-02 14:29:31
---

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8" />
<title>公益404</title>
</head>
<body>
<script type="text/javascript" src="//qzonestyle.gtimg.cn/qzone/hybrid/app/404/search_children.js" homePageName="返回大力的首页" homePageUrl="/"></script>
</body>
</html>

当页面真的找不到时

在 source 目录下创建 404.md 并复制上边的内容。
本地测试时,该页面不能正常显示。在 github.io 上是可正常使用。

关于 Hexo 使用技巧类的内容都在此页更新

开始我的个人博客搭建

发表于 2018-06-28 | 分类于 技术生涯 |

Hexo

首先给出本站点的指导教程:Hexo博客搭建教程 ,真的很详细

感谢前辈位们的付出,因为你们的探路,节约了我们的时间。也因为我们的阅读,你们的教程更有意义。

翻一下历史

今年是2018年,记得2008年刚毕业的时候,同学介绍了一个博客类的项目给我做。甲方据称没有任何特殊需求,只说做的像搜狐博客那样就可以了。我看了看搜狐博客,说到我研究研究,应该是没问题的。时间是一个月,一个月…

当然,项目最后肯定是黄了,甲方不知道自己要什么,我自己不知道自己是什么水平。当时曾在内心发愿,项目黄了,自己将来把项目做完。

回头想想为什么自己如此平庸,而他们却是走向人生巅峰,迎娶白富美,也不是没有原因。

至少自己没有造出一个博客的轮子。

后来工作多年陆,也续接触过各类模板,各类开源的博客,也曾想去填补那个遥远的期许,但都没有实现。

再谈一下选择

技术出身的和,常常搞不清,是要写博客系统,还是要在系统里写博客,最终的小情结就是要有一个自己的个人博客。最终还是要靠内容支持。

即然要写内容,剩下的就是选择一个平台了。从新浪博客,至新浪微博,到QQ空间,博客园,简书,以及gitbook,还有众多的开源博客系统。各种尝试和试用,而今确定使用 hexo+github。

参考点:

  1. hexo 官文自带中文
  2. 主题非常多,亮眼的也很多
  3. 使用者非常多,各类文档好找

本站的重点在于写内容,部署后不再过多折腾技术。

再说我的博客目标

2016年,发现同事在写技术博客,工作中非工作中的小问题,都能写。还记得他的别名“大仲马”(如果你某天看到,请留下你的足迹)。深感自己工作多年,虽然没有什么特别高深的内容,但基础的内容集少成多,偶尔帮助自己及他人,也是好的。

所以从2016年开始,有意开始在“简书”写一些内容,记录工作和生活。但存在2点问题:

  1. 书写质量偏差,包括内容和排版。原因大概是多数时间解决问题后再去写,发现过程的很多问题不值得记录,只记个结果,草草了事。
  2. 更新较少。这个算是中性问题,我是主张少而精,精品需要精力的培育。

这两点问题以后仍会跟随,但意识到了问题,我努力去调整。

仅以此,开始我的博客之路。

Hello World

发表于 2018-06-28 |

文房四宝前,你奉笔让我留下墨宝,我接过笔,沉思片刻,挥毫泼墨间,一行 Hello World 华丽登场

临渊羡鱼,不如退而结网

8 日志
2 分类
7 标签
© 2018
由 Hexo 强力驱动
|
主题 — NexT.Mist v5.1.4