副本集
mongoDB使用副本集提高主从复制的能力,热备能力以及故障转移的能力
构建方式
rs.initiate()
rs.add("localhost:40001")
rs.add("localhost:40002",{arbiterOnly:true})
监控
db.isMasrter()
rs.status()
在k8s中,构建副本集可以直接在配置文件中配置发现
$ cat mongod.conf
systemLog:
path: /var/log/mongodb/mongodb.log
logAppend: true
destination: file
net:
bindIp: 0.0.0.0
storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
mmapv1:
smallFiles: true
wiredTiger:
engineConfig:
cacheSizeGB: 1
# 添加这两句
replication:
replSetName: rs0
而启用了mongo-sidecar,配置其环境变量完成副本在集群中的发现
···
- name: mongo-sidecar # 容器名
image: {{ IMAGEREPOSITORY }}/mongo-k8s-sidecar # 容器镜像
imagePullPolicy: IfNotPresent # 若镜像存在,则不拉取
env: # 环境变量
- name: MONGO_SIDECAR_POD_LABELS
value: "app=mongo"
- name: KUBERNETES_MONGO_SERVICE_NAME
value: "mongo"
- name: KUBERNETES_CLUSTER_DOMAIN
value: {{ DNSDOMAIN }}
···
工作原理
实际上MongoDB对副本集的操作跟mysql主从操作是差不多的
- mysql: 主binlog -> 从relay.log -> 从bin.log -> 从数据库
- mongodb: 主oplog -> 从oplog
写操作先被记录下来,添加到主节点的oplog
里。与此同时,所有从结点复制oplog
。首先,查看自己oplog里最后一条的时间戳;其次,查询主节点oplog
里所有大于此时间戳的条目;最后,把那些条目添加到自己的oplog
里并应用到自己的库里。从节点使用长轮询立即应用来自主结点oplog的新条目。
当遇到以下情况,从节点会停止复制
- 如果从节点在主节点的
oplog
里找不到它所同步的点,那么会永久停止复制 - 一旦某个从节点没能 在主节点的
oplog
里找到它已经同步的点,就无法再保证这个从结点的完美副本
可以使用以下命令查看复刻情况
db.oplog.rs.findOne()
心跳检测与故障转移
每个副本集成员每秒钟ping一次其他所有成员,可以通过rs.status()
看到节点上次的心跳检测时间戳和健康状况。
当主节点出现故障时,mongo副本集会经过投票选择,最后仲裁节点会选择一个副本当选主节点,它可以完美支持故障转移。
如果从节点和仲裁节点都被杀了,只剩下主节点,他会把自己降级成为从节点。仲裁节点不存储数据,只负责故障转移的群体投票
分片
分片是数据库切分的一个概念实现,当数据量过大,索引和工作数据集占用的内存就会越来越多,所以需要通过分片负载来解决这个问题
工作原理
- 分片组件
- 每个分片都是一个副本集
- mongos路由器:是一个路由器,将读写请求指引到合适的分片上
- 配置服务器config:持久化分片集群的元数据,包括:全局集群配置;每个数据库、集合和特定范围数据位置;一份变更记录,保存了数据在分片之间进行迁移的历史信息。配置服务器之间不是副本集形式存在,mongos向配置服务器提交信息时是两阶段提交,保证配置服务器之间的一致性。
- 分片的核心操作
分片一个集合:分片是根据一个属性的范围进行划分的,MongoDB使用所谓的分片键让每个文档在这些范围里找到自己的位置
块:是位于一个分片中的一段连续的分片键范围,可以理解为若干个块组成分片,分片组成MongoDB的全部数据
- 拆分与迁移
块的拆分:初始化时只有一个块,达到最大块尺寸64MB或100000个文档就会触发块的拆分。把原来的范围一分为二,这样就有了两个块,每个块都有相同数量的文档。
块的迁移:当分片中的数据大小不一样时会产生迁移的动作,比如分片A的数据比较多,会将分片A里面的一些块转移到分片B里面去。分片集群通过在分片中移动块来实现均衡,是由名为均衡器的软件进程管理的,任务是确保数据在各个分片中保持均匀分布,当集群中拥有块最多的分片与拥有块最少分片的块差大于8时,均衡器就会发起一次均衡处理。