部署模型java
可复制集node
可复制集是跨多个MongDB服务器(节点)分布和维护数据的方法。mongoDB能够把数据从一个节点复制到其余节点并在修改时进行同步,集群中的节点配置为自动同步数据;旧方法叫作主从复制,mongoDB 3.0之后推荐使用可复制集;算法
为何要用可复制集?它有什么重要性?mongodb
避免数据丢失,保障数据安全,提升系统安全性;
(最少3节点,最大50节点)
自动化灾备机制,主节点宕机后经过选举产生新主机;提升系统健壮性;
(7个选举节点上限)
读写分离,负载均衡,提升系统性能;
生产环境推荐的部署模式;数据库
可复制集架构以及原理apache
oplog( 操做日志) :保存操做记录、时间戳
数据同步:从节点与主节点保持长轮询;1.从节点查询本机oplog最新时间戳;2.查询主节点oplog于此时间戳的全部文档;3.加载这些文档,并根据log执行写操做;
阻塞复制: 与writeconcern相关,不须要同步到从节点的策略(如: acknowledgedUnacknowledged 、w1),数据同步都是异步的,其余状况都是同步;
心跳机制:成员之间会每2s 进行一次心跳检测(ping操做),发现故障后进行选举和故障转移;
选举制度:主节点故障后,其他节点根据优先级和bully算法选举出新的主节点,在选出主节点以前,集群服务是只读的数组
可复制集的搭建过程安全
1. 安装好3个以上节点的mongoDB;
2. 配置mongodb.conf,增长跟复制相关的配置以下:服务器
replication: replSetName: configRS //集群名称 oplogSizeMB: 50 //oplog集合大小
3. 在primary节点上运行可复制集的初始化命令,初始化可复制集,命令以下:架构
//复制集初始化,在主节点上执行,ip禁止使用localhost rs.initiate({ _id: "configRS", version: 1, members: [{ _id: 0, host : "192.168.1.142:27017" }]}); rs.add("192.168.1.142:27018");//有几个节点就执行几回方法 rs.add("192.168.1.142:27019");//有几个节点就执行几回方法
4. 在每一个节点运行rs.status()或isMaster()命令查看复制集状态;
5. 测试数据复制集效果;
6. 测试故障失效转移效果;
Tips:
只能在主节点查询数据,但若是
想在副节点查询到数据需运行
rs.slaveOk(); //每一个节点都运行一次 确保java代码能操做mondodb
代码链接复制集
MongoDB 复制集里Primary 节点是不固定的, 不固定的, 不固定的!因此生产环境千万不要直连Primary, 千万不要直连Primary, 千万不要直连Primary !重要的事情说3 遍!
java原生驱动开发
List<ServerAddress> asList = Arrays.asList( new ServerAddress("192.168.1.142", 27018), new ServerAddress("192.168.1.142", 27017), new ServerAddress("192.168.1.142", 27019)); client = new MongoClient(asList);
Spring配置开发
<mongo:mongo-client replica-set="192.168.1.142:27017,192.168.1.142:27018,192.168.1.142:27017"> </mongo:mongo-client>
配置Tips:
1. 关注Write Concern参数的设置,默认值1能够知足大多数场景的需求。W值大于1能够提升数据的可靠持久化,但会下降写性能。
2. 在options里添加readPreference=secondaryPreferred并打开rs.slaveOk()便可实现读写分离,读请求优先到Secondary节点,从而实现读写分离的功能
分片集群
分片是把大型数据集进行分区成更小的可管理的片,这些数据片分散到不一样的mongoDB节点,这些节点组成了分片集群。
为何要用分片集群?
数据海量增加,须要更大的读写吞吐量 → 存储分布式
单台服务器内存、cpu等资源是有瓶颈的 → 负载分布式
Tips: 分片集群是个双刃剑,在提升系统可扩展性和性能的同时,增大了系统的复杂性,因此在实施以前请肯定是必须的。
什么是分片?
数据库?集合?文档?mongoDB分片集群推荐的模式是:分片集合,它是一种基于分片键的逻辑对文档进行分组,分片键的选择对分片很是重要,分片键一旦肯定,mongoDB对数据的分片对应用是透明的;
Tips:随着数据量的的增大,分片会分割和迁移,以知足数据的均匀分布。
请求分流:经过路由节点将请求分发到对应的分片和块中;
数据分流:内部提供平衡器保证数据的均匀分布,数据平均分布式请求平均分布的前提;
块的拆分:3.4版本块的最大容量为64M或者10w的数据,当到达这个阈值,触发块的拆分,一分为二;
块的迁移:为保证数据在分片节点服务器分片节点服务器均匀分布,块会在节点之间迁移。通常相差8个分块的时候触发;
分片集群架构图与组件
分片:在集群中惟一存储数据的位置,能够是单个mongo服务器,也能够是可复制集,每一个分区上存储部分数据;生产环境推荐使用可复制集
mongos路由:因为分片之存储部分数据,须要mongos路由将读写操做路由到对应的分区上;mongos提供了单点链接集群的方式,轻量级、非持久化因此一般mongos和应用部署在同一台服务器上;
配置服务器:存储集群的元数据,元数据包括:数据库、集合、分片的范围位置以及跨片数据分割和迁移的日志信息;mongos启动时会从配置服务器读取元数据信息在内存中;配置服务器最低3台
分片搭建过程
配置步骤:
1. 分片服务器配置:给27020、27021以及复制集(2701七、2701八、27019)的配置文件增长:
sharding: clusterRole: shardsvr
2. config服务器配置:给复制集(2702二、2702三、27024)的配置文件增长:
sharding: clusterRole: configsvr
3. 启动mongos路由以下:
./mongos --configdb shardingConfig/192.168.1.142:27022,192.168.1.142:27023, 192.168.1.142:27024 --port 27025 -- logpath=/usr/local/apache/mongoDB/sharding/rounter/ mongodb-rounter1/logs/mongodb.log ……
课堂笔记
一.复制集初始化 rs.initiate({ _id: "configRS", version: 1, members: [{ _id: 0, host : "192.168.1.142:27017" }]}); rs.add("192.168.1.142:27018");//有几个节点就执行几回方法 rs.add("192.168.1.142:27019");//有几个节点就执行几回方法 二.分片config复制集初始化 rs.initiate({ _id: "shardingConfig", version: 1, members: [{ _id: 0, host : "192.168.1.142:27023" }]}); rs.add("192.168.1.142:27022");//有几个节点就执行几回方法 rs.add("192.168.1.142:27024");//有几个节点就执行几回方法 三.分片配置步骤 1.分片服务器配置:给27020、27021以及复制集(2701七、2701八、27019)的配置文件增长: sharding: clusterRole: shardsvr 2.config服务器配置:给复制集(2702二、2702三、27024)的配置文件增长: sharding: clusterRole: configsvr 3.启动mongos路由以下: ./mongos --configdb shardingConfig/192.168.1.142:27022,192.168.1.142:27023,192.168.1.142:27024 --port 27025 --logpath=/usr/local/apache/mongoDB/sharding/rounter/mongodb-rounter1/logs/mongodb.log 4.配置sharding 1)链接mongos: mongo --port 27025 2)增长分区: use admin; sh.addShard("192.168.1.142:27020"); sh.addShard("192.168.1.142:27021"); //configRS这个是复制集的名称 sh.addShard("configRS/192.168.1.142:27017,192.168.1.142:27018,192.168.1.142:27019"); 3)经过sh.status()或图形化工具查看分片结果 4)对lison数据库启用分片:sh.enableSharding("lison") 5)对ordersTest集合进行分片,分片键为{"useCode":1,"_id":1} sh.shardCollection("lison.orders",{"useCode":1,"_id":1});
分片注意点与建议
分片注意点:
热点 :某些分片键会致使全部的读或者写请求都操做在单个数据块或者分片上,致使单个分片服务器严重不堪重负。自增加的分片键容易致使写热点问题;
不可分割数据块:过于粗粒度的分片键可能致使许多文档使用相同的分片键,这意味着这些文档不能被分割为多个数据块,限制了mongoDB均匀分布数据的能力;
查询障碍:分片键与查询没有关联,形成糟糕的查询性能。
建议:
不要使用自增加的字段做为分片键,避免热点问题;
不能使用粗粒度的分片键,避免数据块没法分割;
不能使用彻底随机的分片键值,形成查询性能低下;
使用与经常使用查询相关的字段做为分片键,并且包含惟一字段(如业务主键,id等);
索引对于分区一样重要,每一个分片集合上要有一样的索引,分片键默认成为索引;分片集合只容许在id和分片键上建立惟一索引;
最佳实践
1. 尽可能选取稳定新版本64位的mongodb;
2. 数据模式设计;提倡单文档设计,将关联关系做为内嵌文档或者内嵌数组;当关联数据量较大时,考虑经过表关联实现,dbref或者自定义实现关联;
3. 避免使用skip跳过大量数据;(1)经过查询条件尽可能缩小数据范围;(2)利用上一次的结果做为条件来查询下一页的结果;
4. 避免单独使用不适用索引的查询符($ne、$nin、$where等)
5. 根据业务场景,选择合适的写入策略,在数据安全和性能之间找到平衡点;
6. 索引建议很重要;
7. 生产环境中建议打开profile,便于优化系统性能;
8. 生产环境中建议打开auth模式,保障系统安全;
9. 不要将mongoDB和其余服务部署在同一台机器上(mongodb占用的最大内存是能够配置的);
10. 单机必定要开启journal日志,数据量不太大的业务场景中,推荐多机器使用副本集,并开启读写分离;
11. 分片键的注意事项
mongodb.conf
storage: dbPath: "/usr/local/apache/mongoDB/sharding/replication/primary/data" journal: enabled: true directoryPerDB: true engine: wiredTiger wiredTiger: engineConfig: cacheSizeGB: 1 journalCompressor: snappy directoryForIndexes: false collectionConfig: blockCompressor: snappy indexConfig: prefixCompression: true systemLog: destination: file path: "/usr/local/apache/mongoDB/sharding/replication/primary/logs/mongodb.logs" net: port: 27017 http: RESTInterfaceEnabled: true processManagement: fork: false replication: replSetName: configRS oplogSizeMB: 50 sharding: clusterRole: shardsvr
start-sharding-mongodb.sh 启动脚本(测试的mongodb都在同一台机器上的)
nohup ./replication/primary/bin/mongod -f ./replication/primary/bin/mongodb.conf >./logs/primary.log 2>&1 & nohup ./replication/secondary1/bin/mongod -f ./replication/secondary1/bin/mongodb.conf >./logs/secondary1.log 2>&1 & nohup ./replication/secondary2/bin/mongod -f ./replication/secondary2/bin/mongodb.conf >./logs/secondary2.log 2>&1 & nohup ./mongodb-node1/bin/mongod -f ./mongodb-node1/bin/mongodb.conf >./logs/mongodb-node1.log 2>&1 & nohup ./mongodb-node2/bin/mongod -f ./mongodb-node2/bin/mongodb.conf >./logs/mongodb-node2.log 2>&1 & nohup ./config/mongodb-config1/bin/mongod -f ./config/mongodb-config1/bin/mongodb.conf >./logs/config1.log 2>&1 & nohup ./config/mongodb-config2/bin/mongod -f ./config/mongodb-config2/bin/mongodb.conf >./logs/config2.log 2>&1 & nohup ./config/mongodb-config3/bin/mongod -f ./config/mongodb-config3/bin/mongodb.conf >./logs/config3.log 2>&1 & nohup ./rounter/mongodb-rounter1/bin/mongos --configdb shardingConfig/192.168.1.142:27022,192.168.1.142:27023,192.168.1.142:27024 --port 27025 --logpath=/usr/local/apache/mongoDB/sharding/rounter/mongodb-rounter1/logs/mongodb.log >./logs/rounter.log 2>&1 &