在mongo中,oplog.rs集合没有任何索引,从库像主库查询{ts:{$gte:ts}}时会带有oplog_replay位标识,主库接收到这个位标识就认为是oplog同步查询,并对查询做了以下优化:
查询过程优化:
1.默认使用从尾到头的查询方式(Oplog同步的数据一般位于尾部).
2.如果在5s内查不到所需要的数据,将按照extent的顺序,向前查找,确定所需要查找的数据所在的extent.
3.找到包含数据的extent之后,将从extent的头开始向后查找,直到找到数据为止.
按照我们实际的测试,这种同步在机械硬盘可以达到每秒5000条的速度,可以认为在oplog的查询时不存在性能瓶颈.
mongo的oplog使用定长大小的capped extent优化查询,这使得oplog的记录时间难以得到保证,在tokumx中,oplog不再占用固定大小的空间,而是固定记录天数,实际占用大小与实际操作量有关,在从向主查询更新条目时,mongo使用的优化查询相关的代码被取消,取而代之的是原理更为简洁的索引查询.
tokumx的oplog中,_id不再是objectId类型,而是BinData类型,字段记录的数据与时间无关,并且递增,从按照{_id:{$gte:_id}}查询,为提高查询效率,tokumx在_id上建立了索引.
于是在集群间进行数据迁移同步oplog时要做相应修改,并且从某一点开始同步oplog变得不可行.
实际使用过程中,发现这种单纯按照索引查询的效率并不高,日志中出现几百ms甚至几千ms的oplog慢查询,之后为此优化的余地还很大.
oplog格式也做了小改动,ts类型由timestamp变为ISOData,op操作放入ops数组.