HI!, 你好, 我是 zane,zanePerfor 是一款最近我开发的一个前端性能监控平台, 现在支持 web 浏览器端和微信小程序段.
我定义为一款完整, 高性能, 高可用的前端性能监控系统, 这是未来会达到的目的, 现今的架构也基本支持了高可用, 高性能的部署. 实际上还不够, 在很多地方还有优化的空间, 我会持续的优化和升级.
开源不易, 如果你也热爱技术, 拥抱开源, 希望能小小的支持给个 star.
项目的 GitHub 地址:
https://github.com/wangweianger/zanePerfor
项目开发文档说明:
https://blog.seosiwei.com/performance/index.html
分片的概念:
在 MongoDB 中, 分片集群 (sharded cluster) 是一种水平扩展数据库系统性能的方法, 能够将数据集分布式存储在不同的分片 (shard) 上, 每个分片只保存数据集的一部分, MongoDB 保证各个分片之间不会有重复的数据, 所有分片保存的数据之和就是完整的数据集. 分片集群将数据集分布式存储, 能够将负载分摊到多个分片上, 每个分片只负责读写一部分数据, 充分利用了各个 shard 的系统资源, 提高数据库系统的吞吐量.
为什么要分片:
解决高并发时系统吞吐量
解决垂直扩展的价格昂贵成本, 降低成本
提高系统的稳定, 高可用性
提供大数据量时的分布式计算能力
解决单机或副本集的磁盘不足
解决请求量巨大时的内存不足等
MongoDB 分片集群结构分布:
上图中主要有如下所述三个主要组件:
Shard:
用于存储实际的数据块, 实际生产环境中一个 shard server 角色可由几台机器组个一个 replica set 承担, 防止主机单点故障
Config Server:
mongod 配置服务器, 存储了整个 ClusterMetadata, 其中包括 chunk 信息(配置服务器 3.4 起需要是副本集).
Query Routers:
mongos 路由器, 客户端由此接入, 且让整个集群看上去像单一数据库, 前端应用可以透明使用.
分片实例
(备注: 鉴于成本, 以下内容在单机下部署为例, 多机部署只需要替换下 IP 即可)
分片计划
三个 Shard 分片 端口: 27020,27021,27022
三个 Config 服务 端口: 27100,27101,27102
一个 Mongos 路由服务 端口: 30000
创建 Shard 分片目录
- // 创建分片数据和日志存储目录
- mkdir -p /data/mongod/s0
- mkdir -p /data/mongod/s1
- mkdir -p /data/mongod/s2
mkdir -p /data/mongod/log
启动 Shard Server
- mongod --dbpath /data/mongod/s0 --logpath /data/mongod/log/s0.log --fork --smallfiles --port 27020 --shardsvr
- mongod --dbpath /data/mongod/s1 --logpath /data/mongod/log/s1.log --fork --smallfiles --port 27021 --shardsvr
mongod --dbpath /data/mongod/s2 --logpath /data/mongod/log/s2.log --fork --smallfiles --port 27022 --shardsvr
--dbpath: 存储数据目录
--logpath: 存储日志目录
--smallfiles: 是否使用较小的默认文件. 默认为 false
--shardsvr: 是表示以 sharding 模式启动 MongoDB 服务器
提示: 每个 Shard 分片也可以是 MongoDB 副本集
创建 Config Server 目录
- mkdir -p /data/mongod/c0
- mkdir -p /data/mongod/c1
mkdir -p /data/mongod/c2
启动 Config Server
- mongod --dbpath /data/mongod/c0 --logpath /data/mongod/log/c0.log --fork --smallfiles --port 27100 --replSet rs1 --configsvr
- mongod --dbpath /data/mongod/c1 --logpath /data/mongod/log/c1.log --fork --smallfiles --port 27101 --replSet rs1 --configsvr
mongod --dbpath /data/mongod/c2 --logpath /data/mongod/log/c2.log --fork --smallfiles --port 27102 --replSet rs1 --configsvr
--replSet: 副本集名称, 副本集名称必须一致
--configsvr: 是表示以 config 配置服务启动 MongoDB 服务器
提示: 配置服务器需要是 MongoDB 副本集
配置副本集:
- // shell 命令进入 MongoDB
- mongo --port 27100
- // 使用 admin 账户
- use admin;
- // 初始化副本集
- rs.initiate({
- _id:"rs1",members:[{
- _id:0,host:"127.0.0.1:27100"
- },{
- _id:1,host:"127.0.0.1:27101"
- },{
- _id:2,host:"127.0.0.1:27102"
- }]
- })
- // 查看副本集状态
rs.status();
提示: MongoDB 副本集节点的增删非常简单, 增加使用
rs.add("127.0.0.1:27103")
删除使用:
rs.remove("127.0.0.1:27103")
启动 Route Process
mongos --logpath /data/mongod/log/mongo.log --port 30000 --fork --configdb rs1/127.0.0.1:27100,127.0.0.1:27101,127.0.0.1:27102
mongos 服务不存储数据, 因此不需要 dbpath
--configdb 是核心配置, 表示设定 config server 的地址列表, 格式: 副本集名称 / host:prot,host:prot,host:prot 格式.
提示: mongos 路由服务也可以是副本集
配置 Sharding 分片
- // 进入路由服务器
- mongo --port 30000
- // 添加分片
- sh.addShard("127.0.0.1:27020")
- sh.addShard("127.0.0.1:27021")
- sh.addShard("127.0.0.1:27022")
- // 查看分片信息
sh.status();
设置分片数据库与片键
指定需要分片的数据库
sh.enableSharding("performance")
设置分片的片键
MongoDB 如何分片是一门学问, 分的好对数据均衡存储, 查询效率有很高的提升, 分的不好导致分片不均匀, 有的 chunk 太大, 有的太小, 查询效率低下, 需要好好的实践和琢磨.
Sharding 架构下, 如果不手动分片, MongoDB 不会自动分片, 所有数据会存储到一个片中, 所以我们希望分片的表必须手动分片.
分片选择的片键首先需要建立索引.
例如: 下面对 performance 数据库的 pagelist 集合进行分片, 选择 url 为片键.
1, 创建索引
db.pagelist.ensureIndex({"url":1})
2, 设置分片
sh.shardCollection("performance.pagelist",{url:1})
至此分片完毕.
MongoDB 一个 chunk 默认大小为 64M, 当数据量大于 64M 时会重新创建新的 chunk 储存数据.
在 zanePerfor (前端性能监控平台)生产环境中使用 MongoDB 集群分片.
在 zanePerfor 使用集群分片非常简单, 跟单机配置模式是一样的, 只需要更改下端口号即可.
一: 找到项目的 config/config.prod.JS 文件
更改如下 MongoDB 配置即可:
- // MongoDB 服务
- // 此处替换 url 参数为链接副本集方式即可
- const dbclients = {
- db3: {
- // 单路由方式
- url: 'mongodb://127.0.0.1:30000/performance',
- // 路由副本集方式
- url: 'mongodb://127.0.0.1:30000,127.0.0.1:30001,127.0.0.1:30002/performance?replicaSet=mongos',
- options: {
- poolSize: 100,
- keepAlive: 10000,
- connectTimeoutMS: 10000,
- autoReconnect: true,
- reconnectTries: 100,
- reconnectInterval: 1000,
- },
- },
};
二: 分片规则
分片规则初期使用 hashed 分片, 例如 webpages 集合分片方式:
sh.shardCollection("performance.webpages", { "url": "hashed"})
详细的分配规则和性能还在总结和实践中, 调优之后我会放到 GitHub 中.
zanePerfor GitHub 地址:
https://github.com/wangweianger/zanePerfor
zanePerfor 开发文档:
https://blog.seosiwei.com/performance/index.html
来源: https://juejin.im/post/5bed24e2e51d4543cd17334e