Centos-mongodb分片

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: MongoDB中使用分片集群结构1、mongos: 数据库集群请求的入口,所有的请求都通过mongos进行协调,不需要在应用程序添加一个路由选择器,mongos自己就是一个请求分发中心,它负责把对应的数据请求请求转发到对应的shard服务器上。

MongoDB中使用分片集群结构
1、mongos:
数据库集群请求的入口,所有的请求都通过mongos进行协调,不需要在应用程序添加一个路由选择器,mongos自己就是一个请求分发中心,它负责把对应的数据请求请求转发到对应的shard服务器上。在生产环境通常有多mongos作为请求的入口,防止其中一个挂掉所有的mongodb请求都没有办法操作。

2、config server:
顾名思义为配置服务器,存储所有数据库元信息(路由、分片)的配置。mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,配置服务器则实际存储这些数据。mongos第一次启动或者关掉重启就会从 config server 加载配置信息,以后如果配置服务器信息变化会通知到所有的 mongos 更新自己的状态,这样 mongos 就能继续准确路由。在生产环境通常有多个 config server 配置服务器,因为它存储了分片路由的元数据,这个可不能丢失!就算挂掉其中一台,只要还有存货, mongodb集群就不会挂掉。

3、shard:
这就是传说中的分片了。上面提到一个机器就算能力再大也有天花板,就像军队打仗一样,一个人再厉害喝血瓶也拼不过对方的一个师。俗话说三个臭皮匠顶个诸葛亮,这个时候团队的力量就凸显出来了。在互联网也是这样,一台普通的机器做不了的多台机器来做

首先确定各个组件的数量,mongos 3个, config server 3个,数据分3片 shard server 3个,每个shard 有一个副本一个仲裁也就是 3 * 2 = 6 个,总共需要部署15个实例。这些实例可以部署在独立机器也可以部署在一台机器,我们这里测试资源有限,只准备了 3台机器,在同一台机器只要端口不同就可以

解压压缩包

tar zxf mongodb-linux-x86_64-rhel62-3.0.6.tgz
mv mongodb-linux-x86_64-rhel62-3.0.6 mongodb

分别在每台机器建立mongos 、config 、 shard1 、shard2、shard3 五个目录。

mkdir -p /usr/nacp/mongodb/mongos/log
mkdir -p /usr/nacp/mongodb/config/data
mkdir -p /usr/nacp/mongodb/config/log
mkdir -p /usr/nacp/mongodb/shard1/data
mkdir -p /usr/nacp/mongodb/shard1/log
mkdir -p /usr/nacp/mongodb/shard2/data
mkdir -p /usr/nacp/mongodb/shard2/log
mkdir -p /usr/nacp/mongodb/shard3/data
mkdir -p /usr/nacp/mongodb/shard3/log

规划5个组件对应的端口号,由于一个机器需要同时部署 mongos、config server 、shard1、shard2、shard3,所以需要用端口进行区分。这个端口可以自由定义,在本文 mongos为 20000, config server 为 21000, shard1为 22001 , shard2为22002, shard3为22003。

在每一台服务器分别启动配置服务器。

/usr/nacp/mongodb/bin/mongod --configsvr --dbpath /usr/nacp/mongodb/config/data --port 21000 --logpath /usr/nacp/mongodb/config/log/config.log --fork

在每一台服务器分别启动mongos服务器。

/usr/nacp/mongodb/bin/mongos  --configdb 192.168.2.233:21000,192.168.2.235:21000,192.168.2.236:21000  --port 20000   --logpath  /usr/nacp/mongodb/mongos/log/mongos.log --fork

在每一台配置各个分片的副本集。nojournal 是为了关闭日志信息。 oplogsize是为了降低 local 文件的大小

#在每个机器里分别设置分片1服务器及副本集shard1
/usr/nacp/mongodb/bin/mongod --shardsvr --replSet shard1 --port 22001 --dbpath /usr/nacp/mongodb/shard1/data  --logpath /usr/nacp/mongodb/shard1/log/shard1.log --fork --nojournal  --oplogSize 10
#在每个机器里分别设置分片2服务器及副本集shard2
/usr/nacp/mongodb/bin/mongod --shardsvr --replSet shard2 --port 22002 --dbpath /usr/nacp/mongodb/shard2/data  --logpath /usr/nacp/mongodb/shard2/log/shard2.log --fork --nojournal  --oplogSize 10
#在每个机器里分别设置分片3服务器及副本集shard3
/usr/nacp/mongodb/bin/mongod --shardsvr --replSet shard3 --port 22003 --dbpath /usr/nacp/mongodb/shard3/data  --logpath /usr/nacp/mongodb/shard3/log/shard3.log --fork --nojournal  --oplogSize 10

分别对每个分片配置副本集

#设置第一个分片副本集
/usr/nacp/mongodb/bin/mongo  127.0.0.1:22001
#使用admin数据库
use admin
#定义副本集配置
config = { _id:"shard1", members:[
             {_id:0,host:"192.168.2.233:22001",arbiterOnly:true},
             {_id:1,host:"192.168.2.235:22001"},
             {_id:2,host:"192.168.2.236:22001"}
        ]
     }
#初始化副本集配置
rs.initiate(config);

#设置第二个分片副本集
/usr/nacp/mongodb/bin/mongo  127.0.0.1:22002
#使用admin数据库
use admin
#定义副本集配置
config = { _id:"shard2", members:[
             {_id:0,host:"192.168.2.233:22002"},
             {_id:1,host:"192.168.2.235:22002",arbiterOnly:true},
             {_id:2,host:"192.168.2.236:22002"}
        ]
     }
#初始化副本集配置
rs.initiate(config);

#设置第三个分片副本集
/usr/nacp/mongodb/bin/mongo    127.0.0.1:22003
#使用admin数据库
use admin
#定义副本集配置
config = { _id:"shard3", members:[
             {_id:0,host:"192.168.2.233:22003"},
             {_id:1,host:"192.168.2.235:22003"},
             {_id:2,host:"192.168.2.236:22003",arbiterOnly:true}
        ]
     }
#初始化副本集配置
rs.initiate(config);

#mongodb默认是从主节点读写数据的,副本节点上不允许读,需要设置副本节点可以读。
repset:SECONDARY> db.getMongo().setSlaveOk();

设置分片配置,让分片生效。

如里shard是单台服务器,用 db.runCommand( { addshard : “[: ]” } )这样的命令加入,如果shard是副本集,用db.runCommand( { addshard : “replicaSetName/[:port][,serverhostname2[:port],…]” });这样的格式表示 

#连接到mongos
/usr/nacp/mongodb/bin/mongo  127.0.0.1:20000
#使用admin数据库
user  admin。
#串联路由服务器与分配副本集1
db.runCommand( { addshard : "shard1/192.168.2.233:22001,192.168.2.235:22001,192.168.2.236:22001"});
#串联路由服务器与分配副本集2
db.runCommand( { addshard : "shard2/192.168.2.233:22002,192.168.2.235:22002,192.168.2.236:22002"});
#串联路由服务器与分配副本集3
db.runCommand( { addshard : "shard3/192.168.2.233:22003,192.168.2.235:22003,192.168.2.236:22003"});

查看分片服务器的配置

db.runCommand( { listshards : 1 } );
#内容输出
{
     "shards" : [
        {
            "_id" : "shard1",
            "host" : "shard1/192.168.0.136:22001,192.168.0.137:22001"
        },
        {
            "_id" : "shard2",
            "host" : "shard2/192.168.0.136:22002,192.168.0.137:22002"
        },
        {
            "_id" : "shard3",
            "host" : "shard3/192.168.0.136:22003,192.168.0.137:22003"
        }
    ],
    "ok" : 1
}
分片副本集的仲裁节点,所以在上面结果没有列出来。

连接在mongos上,准备让指定的数据库、指定的集合分片生效。

#指定testdb分片生效
db.runCommand( { enablesharding :"testdb"});
#指定数据库里需要分片的集合和片键
db.runCommand( { shardcollection : "testdb.table1",key : {id: 1} } )

我们设置testdb的 table1 表需要分片,根据 id 自动分片到 shard1 ,shard2,shard3 上面去。要这样设置是因为不是所有mongodb 的数据库和表 都需要分片!

测试分片配置结果。

#连接mongos服务器
/usr/nacp/mongodb/bin/mongo  127.0.0.1:20000
#使用testdb
use  testdb;
#插入测试数据
for (var i = 1; i <= 100000; i++) db.table1.save({id:i,"test1":"testval1"});
#查看分片情况如下,部分无关信息省掉了
db.table1.stats();
{
    "sharded" : true,
    "ns" : "testdb.table1",
    "count" : 100000,
    "numExtents" : 13,
    "size" : 5600000,
    "storageSize" : 22372352,
    "totalIndexSize" : 6213760,
    "indexSizes" : {
        "_id_" : 3335808,
        "id_1" : 2877952
    },
    "avgObjSize" : 56,
    "nindexes" : 2,
    "nchunks" : 3,
    "shards" : {
        "shard1" : {
            "ns" : "testdb.table1",
            "count" : 42183,
            "size" : 0,
            ...
            "ok" : 1
        },
        "shard2" : {
            "ns" : "testdb.table1",
            "count" : 38937,
            "size" : 2180472,
            ...
            "ok" : 1
        },
        "shard3" : {
            "ns" : "testdb.table1",
            "count" :18880,
            "size" : 3419528,
            ...
            "ok" : 1
        }
    },
    "ok" : 1
}

java程序调用分片集群,因为我们配置了三个mongos作为入口,就算其中哪个入口挂掉了都没关系,使用集群客户端程序如下:

public class TestMongoDBShards {
 
       public static void main(String[] args) {
 
         try {
          List<ServerAddress> addresses = new ArrayList<ServerAddress>();
          ServerAddress address1 = new ServerAddress("192.168.2.233" , 20000);
          ServerAddress address2 = new ServerAddress("192.168.2.235" , 20000);
          ServerAddress address3 = new ServerAddress("192.168.2.236" , 20000);
          addresses.add(address1);
          addresses.add(address2);
          addresses.add(address3);
 
          MongoClient client = new MongoClient(addresses);
          DB db = client.getDB( "testdb" );
          DBCollection coll = db.getCollection( "table1" );
 
          BasicDBObject object = new BasicDBObject();
          object.append( "id" , 1);
 
          DBObject dbObject = coll.findOne(object);
 
          System. out .println(dbObject);

          //读操作从副本节点读取
          ReadPreference preference = ReadPreference. secondary();
          DBObject dbObject = coll.findOne(object, null , preference);
          System. out .println(dbObject);
 
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
}

primary:默认参数,只从主节点上进行读取操作;
primaryPreferred:大部分从主节点上读取数据,只有主节点不可用时从secondary节点读取数据。
secondary:只从secondary节点上进行读取操作,存在的问题是secondary节点的数据会比primary节点数据“旧”。
secondaryPreferred:优先从secondary节点进行读取操作,secondary节点不可用时从主节点读取数据;
nearest:不管是主节点、secondary节点,从网络延迟最低的节点上读取数据。

    //连接到MongoDB服务 如果是远程连接可以替换“localhost”为服务器所在IP地址  
        //ServerAddress()两个参数分别为 服务器地址 和 端口  
        ServerAddress serverAddress = new ServerAddress("localhost",27017);  
        List<ServerAddress> addrs = new ArrayList<ServerAddress>();  
        addrs.add(serverAddress);  
          
        //MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码  
        MongoCredential credential = MongoCredential.createScramSha1Credential("username", "databaseName", "password".toCharArray());  
        List<MongoCredential> credentials = new ArrayList<MongoCredential>();  
        credentials.add(credential);  
          
        //通过连接认证获取MongoDB连接  
        MongoClient mongoClient = new MongoClient(addrs,credentials);
MongoClientOptions.Builder build = new MongoClientOptions.Builder();  
//与数据最大连接数50  
  build.connectionsPerHost(50);  
//如果当前所有的connection都在使用中,则每个connection上可以有50个线程排队等待  
build.threadsAllowedToBlockForConnectionMultiplier(50);  
build.connectTimeout(1*60*1000);  
build.maxWaitTime(2*60*1000);  
MongoClientOptions options = build.build();  
MongoClient client = new MongoClient("127.0.0.1", options); 
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
运维 NoSQL 安全
【最佳实践】高可用mongodb集群(1分片+3副本):规划及部署
结合我们的生产需求,本次详细整理了最新版本 MonogoDB 7.0 集群的规划及部署过程,具有较大的参考价值,基本可照搬使用。 适应数据规模为T级的场景,由于设计了分片支撑,后续如有大数据量需求,可分片横向扩展。
1138 1
|
18天前
|
存储 NoSQL 前端开发
MongoDB 分片
10月更文挑战第17天
26 2
|
2月前
|
存储 监控 NoSQL
*MongoDB的水平扩展主要通过分片技术实
*MongoDB的水平扩展主要通过分片技术实
42 5
|
2月前
|
存储 NoSQL 前端开发
MongoDB 分片总结
这篇文章总结了MongoDB分片的概念、集群结构、分片实例、配置和测试过程。
55 6
|
6月前
|
存储 负载均衡 NoSQL
MongoDB分片技术:实现水平扩展的利器
【4月更文挑战第30天】MongoDB的分片技术是应对数据增长和复杂业务需求的解决方案,它将数据水平拆分存储在多个实例上,实现数据库的水平扩展。分片带来水平扩展性、负载均衡、高可用性和灵活的数据管理。分片工作涉及mongos路由进程、config server和shard实例。设置分片包括部署配置服务器、添加分片、启动mongos、配置分片键和开始分片。选择合适的分片键和有效管理能确保系统性能和稳定性。
|
3月前
|
存储 运维 NoSQL
轻松上手:逐步搭建你的高可用MongoDB集群(分片)
【8月更文挑战第13天】在数据激增的背景下,传统单机数据库难以胜任。MongoDB作为流行NoSQL数据库,采用分片技术实现水平扩展,有效处理海量数据。分片将数据分散存储,提高并发处理能力和容错性,是高可用架构基石。构建MongoDB集群需理解shard、config server和router三组件协同工作原理。通过具体实例演示集群搭建流程,包括各组件的启动及配置,确保数据高可用性和系统稳定性。合理规划与实践可构建高效稳定的MongoDB集群,满足业务需求并支持未来扩展。
81 0
|
6月前
|
NoSQL 算法 测试技术
【MongoDB 专栏】MongoDB 的自动分片与手动分片
【5月更文挑战第11天】MongoDB的分片技术在处理大规模数据和高并发场景中至关重要,提供自动和手动两种方式。自动分片基于预定义规则,简化管理,适合大部分场景,但灵活性有限。手动分片则允许用户自定义策略,实现高效布局,适用于有特殊需求的应用,但配置复杂。选择分片方式需考虑业务需求、数据特点和技术能力。正确实施分片策略能构建高性能、可扩展的系统,支持企业业务发展。随着技术进步,未来的分片技术将更加智能和易用。
174 3
【MongoDB 专栏】MongoDB 的自动分片与手动分片
|
6月前
|
存储 监控 NoSQL
【MongoDB 专栏】MongoDB 分片策略与最佳实践
【5月更文挑战第10天】MongoDB 分片是应对大数据量的扩展策略,涉及哈希和范围分片两种策略。分片架构包含分片服务器、配置服务器和路由服务器。最佳实践包括选择合适分片键、监控调整、避免热点数据等。注意数据分布不均和跨分片查询的挑战。通过实例展示了如何在电商场景中应用分片。文章旨在帮助理解并优化 MongoDB 分片使用。
242 3
【MongoDB 专栏】MongoDB 分片策略与最佳实践
|
5月前
|
存储 负载均衡 NoSQL
MongoDB的分片功能
【6月更文挑战第6天】MongoDB的分片功能
62 1
|
4月前
|
NoSQL Linux MongoDB
Centos7安装MongoDB
Centos7安装MongoDB
484 0