终于有机会在实际工作中使用mongodb了,毕竟之前都只是稍稍玩一下,没有在真正接触之前就是各种好,感觉mysql简直差得远了,业务多变,加个字段都要锁表,数据量大嘛,分表又得依赖中间件,官方还没有提供方案的那种。但是实际用过mongodb之后,感觉mysql其实也是很可爱的。
使用背景
业务是游戏运营,除了一般的后台之外,还需要管理大量的数据,这个量又不到非要使用hadoop和spark之类,毕竟无论是维护还是价格上成本都不低。之前都是使用mysql来进行日志数据和报表数据的储存的。实际使用中mysql会有诸多不方便,后来终于实际使用了mongodb来替换mysql,本篇是记录使用中的差别,其实mongodb没有想象中的万能,mysql也没有想象中的差。
不同业务中的使用感想
日志储存
要储存收集来的数据,需要解决几个问题。写入速度、文件保存的问题。
- 写入。在写性能上,mongodb会更胜一筹,不过我们有使用队列来处理数据,原始数据进入队列,然后经过一步一步的处理之后才进行数据库的写入操作,因此这个写入的问题并没有太大的影响。
- 文件保存。mongo官方则提供了完善的集群方案,简单地实现mongodb集群搭建,另外mongodb的ReplicaSet让数据备份更加方便,反观mysql,做分表只能依赖非官方的中间件,表一大了,从库就不好做了。之前对于mysql的处理方案是使用冷热数据的处理方式,只保留热数据(例如最近3个月的数据),其他数据迁移到一个冷数据表中,操作起来还是挺香的,缺陷就是统计时候会有麻烦(后面说)。
报表统计
要说数据,肯定离不开报表汇总,我们的数据除了要满足整公司的各个部门,统计维度自然多,例如根据游戏汇总、根据渠道包汇总、根据用户汇总、根据投放渠道汇总等。
在汇总上,无论是mongodb还是mysql,都是使用中间表的方案,即先将日志表根据维度先汇总成一张张大表,例如按日期+游戏+渠道表的维度汇总激活、登录、付费等数据,然后实际使用的报表则是建立在这些中间表之上,通过对中间表的指定维度汇总出业务部门需要的数据。
对于mysql,如果使用上了分表结构,那么在汇总的时候如果跨表那就头疼了,对于不使用分表结构的话,冷热数据+分区方案就非常够用了。而mongo由于官方提供了方便的搭建集群的方式,所以在大数据下的读取也是不错的,不过由于InnoDB使用B+树结构,而mongodb采用B数结构,所以mysql在范围搜索上要优于mongodb,但是如果是唯一索引搜索这一类就mongodb要更优秀了。
报表的处理,除了单表汇总之外。还会出现多表的联合汇总的,例如要某天登录数+注册数+留存2、3、4。。。60。对于登录、注册信息是放在一张表,而留存这里则是通过另外一个注册日期+登录日志维度的表来汇总的,这种情况下,mysql只要建立好适当的索引,及时join之后也是没有问题,但是mongodb呢?lookup?不要提它,提起就来气,而且mongodb在project或者unwind之后是无法使用索引的。最后在mongodb上的处理方案是再增加一个表来记录天维度的留存2、3、4、。。。。60。
业务变化导致结构修改
这个情况会更加多,由于业务需求,需要在日志或者汇总表中增加字段,mysql的表结构修改灾难就来了,因为mysql修改表结构是要锁表的呀,mongodb就随意了,不过mongodb字段是有类型的,一开始的时候就会因为不小心将id储存成了string类型,导致在搜索的时候要将id由int类型转化成string才能搜索,于是后面还是在写入逻辑层上,为mongodb增加了schema配置,不过总体上来说mongodb在这一场景下是比mysql方便很多的。
总体感受
myslq在大数据时代是落后了(虽然绝大部分公司都用不上大数据),而新诞生的mongodb更好的顺应了这个大数据时代,无论是分布式方案还是数据筛选上都要优于mysql,不过会有一种怪胎的感觉,抛弃了schema之后真的很容易变成一个垃圾场,另外在范围搜索和聚合上明显的吃力。比较倾向是mongodb来做日志储存,然后中间表上则使用mysql配合冷热数据处理。最近听说在尝试hadoop,不知道啥时候能用上哎。