使用mongodb的findAndModify命令来进行数据同步
来源:互联网 发布:域名注册管理机构 编辑:程序博客网 时间:2024/05/20 05:24
一、问题定义:
由于业务需求,需要实现给一条记录分配一个int值的不重复id,由于是多实例部署的服务,所以如何进行数据同步,避免插入重复id成为关键。
二、解决过程:
1.一开始想到的是,当系统初始化的时候,读取mongo库,找到当前最大的id值,加载到内存,然后多线程之间通过AtomicInteger
进行调用,获取下一个要使用的id值。这样,虽然单实例可以很好的工作,并发也没有问题。但是多实例却无法工作,因为实例与实例之间无法进行协调分配id。
2.接着又想借助与让每个实例都有一个前缀来标识,然后再进行分配id,但是这样,服务重启等问题需要额外一些工作去保证数据一致性。
3.可以把整个业务表加锁,每次插入让其id自增,但是会很影响性能。
三、最终方案:
最终发现了mongo db中有一个原子操作函数findAndModify,它可以指定将获取某个键并同时进行增长一定的值。完全符合我们的场景需求,所以新建一个表,用来记录当前的id值,然后即使多个实例之间想要获取id值,只要调用此函数即可,便可安全获得自增的唯一id值。保证多个服务之间通过原子操作这个表进行了id的同步,避免了id值的重复分配。
使用方式如下,我用的是spring boot,先定义一个mongo表的映射实体:
import lombok.Data;import org.springframework.data.mongodb.core.mapping.Document;@Data@Document(collection = "sequence")public class SequenceId { private String collName; private Integer qid;}
package com.baidu.aibot.backoffice.console.faq.dao;import com.baidu.aibot.backoffice.console.faq.vo.SequenceId;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.mongodb.core.FindAndModifyOptions;import org.springframework.data.mongodb.core.MongoTemplate;import org.springframework.data.mongodb.core.query.Criteria;import org.springframework.data.mongodb.core.query.Query;import org.springframework.data.mongodb.core.query.Update;import org.springframework.stereotype.Service;import java.util.ArrayList;import java.util.List;@Servicepublic class QidMongoDao { private static Logger logger = LoggerFactory.getLogger(QidMongoDao.class); @Autowired private MongoTemplate mongoTemplate; /** * 获取下一段自增ID * * @param collName 集合名称,要同步的ID是用在哪里的 * @param num 增长num大小 * @return 最后的id值 */ private SequenceId getNextId(String collName, int num) { Query query = new Query(Criteria.where("collName").is(collName)); Update update = new Update(); update.inc("qid", num); FindAndModifyOptions options = new FindAndModifyOptions(); // 先查询,如果没有符合条件的,会执行插入,插入的值是查询值 + 更新值 options.upsert(true); // 返回当前最新值 options.returnNew(true); SequenceId seq = mongoTemplate.findAndModify(query, update, options, SequenceId.class); return seq; }}
当前mongo db已经实现了文档级别的锁,性能得到了较大提高,如下是不同版本的mongo所使用的锁的级别:
Version < 2.2 : 只支持进程级锁,一个Mongod实例一个锁。2.8 >Version >= 2.2 : 支持库级锁,一个db一把锁。大于3.0.0 支持文档级别的锁。
四、参考资料
http://www.leftso.com/blog/268.html
http://blog.csdn.net/qq_16313365/article/details/72781469
阅读全文
0 0
- 使用mongodb的findAndModify命令来进行数据同步
- findAndModify函数的使用
- findAndModify与update更新的使用
- mongodb,update和 findAndModify操作。
- mongoclient findandmodify使用
- mongodb-findAndModify(来源于mongodb权威指南)
- 使用dispatch_group来进行线程同步
- 使用MONGODB 集群的OPLOG 日志进行数据恢复
- 使用HTML5 的跨域通信机制进行数据同步
- 使用rsync命令同步数据
- 使用rsync命令同步数据
- 使用rsync命令同步数据
- 使用rsync命令同步数据
- 使用MERGE命令同步数据
- C# Collection.FindAndModify 方法 使用
- kettle和MongoDB之间的数据同步
- logstash-out-mongodb实现elasticsearch到Mongodb的数据同步
- MongoDB中使用MapReduce来进行聚合操作
- 错误笔记:JDBC中Statement和PreparedStatement对于Date类型写入数据库问题
- LM c语言代码
- MyBatis源码(五)之动态Sql解析运行阶段参数处理
- chrome谷歌浏览器开启webgl
- 53.Maximum Subarray
- 使用mongodb的findAndModify命令来进行数据同步
- 【Scikit-Learn 中文文档】交叉分解
- PHP重置数组为连续数字索引的几种方式
- C# ConcurrentStack实现
- linux下生成core dump文件方法及设置 bug定位
- MyBatis初学
- Mat和IplImage访问像素的方法总结
- gpio学习
- 2017年11月12日所看链接(GSON 泛型 下载)