背景
需求要根据商家名称、经纬度对商家列表进行地理位置检索和全文检索,目前这部分数据是缓存在 MongoDB 上,虽然说 MongoDB 支持全文索引,但是对于中文检索,MongoDB 似乎做的还不是非常好,线上也会经常出现查询超时的情况。所以经过考虑研究后,决定改用 Elasticsearch 作为搜索引擎。
目前线上的百万数据需要同步到 Elasticsearch,那么如何能够安全又快速的实现大数据量的同步呢?
方案验证
测试数据量: 200w
方案一:单线程同步
线程数 | 耗时 |
---|---|
1 | 1h |
单线程跑对于应用来说是非常安全的,但是在时间效率上,确实不太能容忍。
方案二:多线程
把同步数据分成多份,使用多线程同步
与上面单线程相比,这个速率可以说是一个质的飞跃。
线程数 | 耗时 |
---|---|
4 | 5 min |
5 | 4 min |
8 | 2.5 min |
16 | 1.6 min |
线程类型分为:CPU 密集型 、 IO 密集型
很显然这是属于 IO 类型,瓶颈应该是在 MySQL 和 ES 的 IO 上,所以理论上线程数越多处理速度越快,这也跟上面的数据符合一致。
当然也不是线程数越多越好,CPU 核数就那么几个,线程数多了上下文切换的耗时也会增加,应用的其他业务也会被影响到。所以在全局的考虑下,选择最合适的 8 个线程数。
因为要等待所有的线程数完成任务,才算是完成整个同步的任务。这里使用了 CountDownLatch 作为计数器:
countDownLatch = new CountDownLatch