最近帮同学做数据分析,作为一名菜鸡,第一次用Python,第一次接触科学计算,第一次使用千万级别的MySQL数据库。帮没帮到忙我不知道,但是这过程中遇到了许多有意思&疑惑的事情,特此记录下来,方便以后避坑。
1、余弦相似度
刚听到这个名词的时候我是懵逼的,后来百度了一下,发现核心算法其实几行代码就能解决。也不用导入啥三方库,毕竟我都还不知道有啥好用的库,主要的难点在于数据格式的处理以及矩阵运算。另外,由于第一次上手Python,90%的时间用来查Python的基础语法了。
2、链路预测
这个相比余弦相似度就进阶了很多,因为不能用Python自带的库写了,需要很多第三方科学计算的库。Anaconda是第一个坑,不过配置好了之后,真是方便,不需要install第三方库的时候等它慢慢下载了。主要需要搞清楚的就是和独立安装的Python之间的关系。另外,PyCharm的venv也需要理解,可以想象成复制一个运行环境。Anaconda其实也就是新建了一个包含很多库的运行环境。这些都是基础的环境配置问题。
然后就是链路预测的实现,最开始准备用Networkx这个库来解决,以为很简单,毕竟只需要调用一下API。不过由于本人第一次接触,实在菜鸡,虽然在官网把Networkx的文档都看完了,但是因为全英文可能理解有点偏差,未能顺利实现。而百度Networkx相关中文资料又太少,国内StackOverflow访问速度又太慢,不得不放弃。最后在Github上找到了链路预测的相关代码,改了改发现可以运行,就交给同学去处理了。
3、十万级别?百万级?千万级.sql文件导入
同学找我的时候,说已经导入完毕了,不过每导入一个.sql文件基本都要一个晚上,另外后期查询的时候,程序经常无响应,而且数据量和预期有很大偏差。我看了看同学电脑里2012年创建的MySQL文件,以及不知道从哪搞的免安装绿色版Navicat,心一横,跟同学说:从头开始!于是踏上了不断测试不断失败的不归路QAQ
我先是教同学在官网下载了最新版的MySQL,然后发现有官方的GUI——Workbench,想着官方的应该正宗一点,就决定放弃使用Navicat。作为一名菜鸡,凭借着仅存的一点印象,连上了数据库,开始导入.sql文件。先试试自带的Data Import吧,结果程序直接卡死,未响应...这真是官方自带GUI工具吗???
试试命令行吧,在黑框框里敲下source X:/XXX之后,一堆OK飞速闪过,CPU占用70%,磁盘占用60%,感觉有戏!闲着无聊&不甘心,研究了一下Workbench,发现有个Dashboard可以监控数据库状态,一看INSERT性能,25行/s???换个性能强劲的笔记本再试试,250行/s???同学说第一个.sql文件大概有80W行,80W/250/3600=54分钟,还可以啊,比同学之前跑一晚上快多了!愉快地去吃火锅~
三小时后,回来一看,怎么还在跑?不是应该早就结束了吗?百度一下看看是不是有什么参数不太对。“千万级别数据库,优化后仅需3分钟”,我的天,可以这么快的吗?原来是配置my.ini文件啊。行吧依葫芦画瓢,我电脑性能还可以,推荐设置8-64?那就设置64!最大80%的内存容量?先设置个10240M,不够再加!为了安全性降低I/O性能?不要安全性了!总之就是有推荐参数了顶格设置,没推荐参数的,选个吉利的大数字!再source一遍,750行/s,算了算18分钟就能跑完,稳!
又过了一小时,一看table参数,怎么都200W行了还不停啊?什么情况?这.sql里面有死循环?黑盒测试怎么行?下个VSCode打开看一看,好家伙,全是一行一行的INSERT,啥优化写法都没有,怪不得这么慢,而且...个十百千万、十万、百万...这不是80W啊,这是800W!同学怎么数的!800W/750/3600=3小时?不行太慢了!等等,下一个文件有多少行?2200W?!不行,这要猴年马月啊...手动优化一下.sql文件吧,800W行INSERT,这怎么优化都麻烦啊,就加个事务吧,死马当活马,再source一下,5K行/s!预计半小时,可以啦,交差!作为不折腾会死星人,怎么闲得住,会不会有什么参数能更快?拿同学性能稍差的笔记本试试吧,结果也是卡在5K行/s上不去。百思不得其解,算了,就这样吧,凌晨两点了,先睡觉。
4、第三方秒杀官方
第二天,第二个.sql文件,2200W行,怎么就卡在5K行/s上不去呢?我就不信邪,网上那么多插入速度上W的,要不试试第三方的GUI吧,存在即合理嘛。同学电脑里装的这个免安装绿色版Navicat可能没配置好,去官网下载了最新的Navicat12。试用14天?行吧,反正帮同学跑完这个项目应该就用不到了。
居然还有中文版,真不错,这界面用得真是比官网顺手多了!运行SQL文件,有进度条,有已生效行数,有已运行时间,比之前黑框框看着舒服多了!这速度也还可以啊,1.2W行/s,秒杀官方工具!果然是存在即合理!优秀!
5、奇怪的蓝屏和Python Memory Error
数据库导入成功,然后就是导出需要的数据到txt,好慢啊...问同学,为啥非要txt啊?随便选的,囧。之前那么多科学计算的库,好像都有CSV文件输出,那就试试吧,果然比txt快了不少!很好,接下来就是算极大连通图!真是顺利得令人安心~程序RUN起来,音乐响起来~动次打次~怎么蓝屏了?Memory Management,难道上个月加装的内存有坏块?用 Windows自带的内存检测跑了快一个小时,无任何问题...怕不是玄学,不管了,重新来!
这次看着跑,免得又出问题。程序RUN起来,内存占用稳步上升,4G、5G、6G、7G...11G、12G、12.5G,突然降到5G,跑完了?切换回来一看,一堆的Memory Error...什么情况啊,Networkx读取edgelist时内存错误?不会啊,内存还没占满啊。跟Networkx库内部数据有关?上Gihub,issues里没人反馈啊,应该不是这个问题。跟PyCharm有关?分配2048M的内存空间!重启一下?还是不行啊...难道是数据格式有问题?不会啊,别人给的数据库,很多人都用的这个,应该不会有这么低级的错误啊。在Stack Overflow和StackExchange上搜了个遍,都不对啊。难道我有的库是32位的?不会啊,都读取了8G才弹错误。烦!
仔细想想,我的操作都没问题啊,软件也都是官网下载的,Anaconda也重新配置了一遍。到底什么情况啊,每次都12.5G的时候内存错误,甚至有几次PyCharm直接崩溃掉,再试试吧。诶?怎么关掉MySQL之后,内存只占用到10.5G,但是能顺利跑出结果。难道真是内存在12.5G有坏快?不会啊,平时打游戏、刷B站,早就用满过16G了啊。真是奇怪,不断测试MySQL和运行程序报错之间的关系...怎么跑程序的时候,MySQL服务起不来?“本地计算机上的mysql服务启动停止后,某些服务在未由其他服务或程序使用时将自动停止“,什么鬼?难道MySQL和PyCharm还冲突不成,不应该啊,那用PyCharm连数据库跑程序的时候不是必死无疑?那么多程序员早就应该发现这个BUG了啊!
等等,难道说是我之前乱设置MySQL的my.ini参数的原因?改回默认吧!
果然!
我的猜测:之前为了让MySQL读大数据,把my.ini里各种缓存都设置的比较大。虽然任务管理器看着内存剩余很多,其实很多已经被MySQL预留了。然后Python运行的时候,查询到的剩余空间是包含了MySQL的预留空间的,于是乎Python把MySQL预留的空间也吃了,然后MySQL服务检测到内存异常之后就重新刷写了内存,于是Python就Memory Error了。
以上只是作为小白的猜测,不保证原理正确!
以上。
记于2019年1月21日