公司用mongodb也有些年头了.不过数据量都不算太大,今天永哥发来一篇文章,讲述Scrapinghub在使用mongodb时遇到的一些问题.Scrapinghub是一家做爬虫数据服务的公司,提供爬虫和数据服务.
原文地址:mongo-bad-for-scraped-data/
Why MongoDB is a bad choice for storing our scraped data
早期Scrapinghub选择mongo的理由和我们一样,简单,动态模型,很简单的配置就能支持很高的数据量.后来经过了很多项目,发现了现在架构的局限性,最终决定替换掉mongodb.理由如下:
锁
Scrapinghub有大量的快速查询(可能就是根据id或者url进行单条或者少量查询)以及少量的慢查询(导出,过滤,批量查询,排序等等).当其中的几个操作同时运行时,连接就会争用锁,造成性能降低.
每一个mongo的服务(2.2以前)都有一个读写锁.由于锁争用造成快查询等待很长而慢查询等待的更长!!当快速查询等待超时之后会进行重试,这么长的时间造成了整个mongo服务的阻塞,比如用户数据的查询,以至于后面拖垮整个应用.造成网站和爬虫全部停止运行
为了解决这些问题.Scrapinghub做了不少的处理.
* 修改了mongodb的驱动的超时和重试处理策略
* 同步数据到新的后端存储以进行批量查询
* 建立了很多mongodb的服务和数据分区
* 增加硬件
* 推迟实现(或者停止了)某些实时性很强的功能
当然mongo2.2之后把锁的级别控制到了db级别,性能有了一定的提高,但是没有直接把锁控制在collection级别,说是还在研发,但是好久了,依然木有消息呀.
低效的空间利用
mongodb并不会自动回收删除的对象及其占用的空间.手动回收需要停机才行.mongodb会尝试重用空间来插入新的对象,但是Scrapinghub的数据非常分散,而且也没有时间来停机维护这些数据.
总是存储字段名称,这样是很浪费空间的,尤其是在某些collection永远不会修改的情况下.
这个也是我们头疼的地方,因为有些数据频繁修改删除,造成空间浪费非常严重.而你又不能停机.烦躁啊.
数据库泛滥
这个可能是Scrapinghub本身业务的问题,Scrapinghub是做数据抓取服务的,每个客户定义的数据模型都不一致,能使用了多个数据库存储?(猜测哈),mongodb会为数据库初始化大小,但是有些数据库又没被使用,造成了空间浪费,其次,在mongo服务重启之后,因为mongo要检查每个数据库,所以会造成启动很慢.
数据排序
有些数据(爬虫抓取日志)需要顺序的写入,当数据库记录非常多的时候进行返回数据排序的检索是非常不切实际的(很慢?好像是)
下面这句没明白..
It is only possible to maintain order in MongoDB if you use capped collections, which are not suitable for crawl output.
skip和limit很慢
总得来说就是mongodb在处理skip和limit的设计上有问题,百万级别就会很缓慢,这个情况我们也遇到过,有些人通过并发来解决,反而会造成服务负债过高,锁争用.
限制
有一些奇怪的限制,比如一些字段的保留字符,这个我们到没有遇到,就不多说了.
不能在内存中处理所有的热数据
Scrapinghub有很多TB级别的数据节点(好像描述的不对),经常访问的数据很小,足够完全放到内存里.因为经常访问的数据大部分是爬虫顺序扫描抓取的.
mongodb没有给用户控制权以设定内存中的热数据,所以经常被访问的数据可能分布在很多的块上,当只有一次数据访问的时候,没有办法阻止mongo频繁的更新内存中的数据,一旦一些数据不经常被访问,mongodb就会出现io和锁的问题.
其他的一些问题
包括事物,隐藏失败,2呵呵的安全模式,没有join等..(你当时选择的时候就知道呀,哈哈哈,下面也有评论吐槽)...
后来Scrapinghub切换到hbase了.下面是他们的一篇文章.
Comments