搭建高可用mongodb集群(四)—— 分片

释放双眼,带上耳机,听听看~!

按照上一节中《搭建高可用mongodb集群(三)—— 深入副本集》搭建后还有两个问题没有解决:

  • 从节点每个上面的数据都是对数据库全量拷贝,从节点压力会不会过大?
  • 数据压力大到机器支撑不了的时候能否做到自动扩展?

在系统早期,数据量还小的时候不会引起太大的问题,但是随着数据量持续增多,后续迟早会出现一台机器硬件瓶颈问题的。而mongodb主打的就是海量数据架构,他不能解决海量数据怎么行!不行!“分片”就用这个来解决这个问题。

传统数据库怎么做海量数据读写?其实一句话概括:分而治之。上图看看就清楚了,如下 taobao岳旭强在infoq中提到的 架构图:

上图中有个TDDL,是taobao的一个数据访问层组件,他主要的作用是SQL解析、路由处理。根据应用的请求的功能解析当前访问的sql判断是在哪个业务数据库、哪个表访问查询并返回数据结果。具体如图:

说了这么多传统数据库的架构,那Nosql怎么去做到了这些呢?mysql要做到自动扩展需要加一个数据访问层用程序去扩展,数据库的增加、删除、备份还需要程序去控制。一但数据库的节点一多,要维护起来也是非常头疼的。不过mongodb所有的这一切通过他自己的内部机制就可以搞定!顿时石化了,这么牛X!还是上图看看mongodb通过哪些机制实现路由、分片:

从图中可以看到有四个组件:mongos、config server、shard、replica set。

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

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

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

一台机器的一个数据表 Collection1 存储了 1T 数据,压力太大了!在分给4个机器后,每个机器都是256G,则分摊了集中在一台机器的压力。也许有人问一台机器硬盘加大一点不就可以了,为什么要分给四台机器呢?不要光想到存储空间,实际运行的数据库还有硬盘的读写、网络的IO、CPU和内存的瓶颈。在mongodb集群只要设置好了分片规则,通过mongos操作数据库就能自动把对应的数据操作请求转发到对应的分片机器上。在生产环境中分片的片键可要好好设置,这个影响到了怎么把数据均匀分到多个分片机器上,不要出现其中一台机器分了1T,其他机器没有分到的情况,这样还不如不分片!

replica set,上两节已经详细讲过了这个东东,怎么这里又来凑热闹!其实上图4个分片如果没有 replica set 是个不完整架构,假设其中的一个分片挂掉那四分之一的数据就丢失了,所以在高可用性的分片架构还需要对于每一个分片构建 replica set 副本集保证分片的可靠性。生产环境通常是 2个副本 + 1个仲裁。

说了这么多,还是来实战一下如何搭建高可用的mongodb集群:

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

架构搭好了,安装软件!

  • 1、准备机器,IP分别设置为: 192.168.0.136、192.168.0.137、192.168.0.138。

  • 2、分别在每台机器上建立mongodb分片对应测试文件夹。


1
2
3
4
5
6
7
8
9
10
1#存放mongodb数据文件
2        
3
4        
5
6
7          mkdir
8           -p 
9          /data/mongodbtest
10

1
2
3
4
5
6
7
8
9
1#进入mongodb文件夹
2        
3
4        
5
6
7          cd 
8           /data/mongodbtest
9
  • 3、下载mongodb的安装程序包


1
2
3
4
5
6
1wget http:
2          //fastdl
3          .mongodb.org
4          /linux/mongodb-linux-x86_64-2
5          .4.8.tgz
6

1
2
3
4
5
6
7
8
9
1#解压下载的压缩包
2        
3
4        
5
6
7          tar
8           xvzf mongodb-linux-x86_64-2.4.8.tgz
9
  • 4、分别在每台机器建立mongos 、config 、 shard1 、shard2、shard3 五个目录。

因为mongos不存储数据,只需要建立日志文件目录即可。


1
2
3
4
5
6
7
8
9
10
1#建立mongos目录
2        
3
4        
5
6
7          mkdir
8           -p 
9          /data/mongodbtest/mongos/log
10

1
2
3
4
5
6
7
8
9
10
1#建立config server 数据文件存放目录
2        
3
4        
5
6
7          mkdir
8           -p 
9          /data/mongodbtest/config/data
10

1
2
3
4
5
6
7
8
9
10
1#建立config server 日志文件存放目录
2        
3
4        
5
6
7          mkdir
8           -p 
9          /data/mongodbtest/config/log
10

1
2
3
4
5
6
7
8
9
10
1#建立config server 日志文件存放目录
2        
3
4        
5
6
7          mkdir
8           -p 
9          /data/mongodbtest/mongos/log
10

1
2
3
4
5
6
7
8
9
10
1#建立shard1 数据文件存放目录
2        
3
4        
5
6
7          mkdir
8           -p 
9          /data/mongodbtest/shard1/data
10

1
2
3
4
5
6
7
8
9
10
1#建立shard1 日志文件存放目录
2        
3
4        
5
6
7          mkdir
8           -p 
9          /data/mongodbtest/shard1/log
10

1
2
3
4
5
6
7
8
9
10
1#建立shard2 数据文件存放目录
2        
3
4        
5
6
7          mkdir
8           -p 
9          /data/mongodbtest/shard2/data
10

1
2
3
4
5
6
7
8
9
10
1#建立shard2 日志文件存放目录
2        
3
4        
5
6
7          mkdir
8           -p 
9          /data/mongodbtest/shard2/log
10

1
2
3
4
5
6
7
8
9
10
1#建立shard3 数据文件存放目录
2        
3
4        
5
6
7          mkdir
8           -p 
9          /data/mongodbtest/shard3/data
10

1
2
3
4
5
6
7
8
9
10
1#建立shard3 日志文件存放目录
2        
3
4        
5
6
7          mkdir
8           -p 
9          /data/mongodbtest/shard3/log
10
  • 5、规划5个组件对应的端口号,由于一个机器需要同时部署 mongos、config server 、shard1、shard2、shard3,所以需要用端口进行区分。

这个端口可以自由定义,在本文 mongos为 20000, config server 为 21000, shard1为 22001 , shard2为22002, shard3为22003.

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


1
2
3
4
5
6
7
8
9
1/data/mongodbtest/mongodb-linux-x86_64-2
2          .4.8
3          /bin/mongod
4           --configsvr --dbpath 
5          /data/mongodbtest/config/data
6           --port 21000 --logpath 
7          /data/mongodbtest/config/log/config
8          .log --fork
9
  • 7、在每一台服务器分别启动mongos服务器。


1
2
3
4
5
6
7
1/data/mongodbtest/mongodb-linux-x86_64-2
2          .4.8
3          /bin/mongos 
4           --configdb 192.168.0.136:21000,192.168.0.137:21000,192.168.0.138:21000  --port 20000   --logpath  
5          /data/mongodbtest/mongos/log/mongos
6          .log --fork
7
  • 8、配置各个分片的副本集。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1#在每个机器里分别设置分片1服务器及副本集shard1
2        
3
4        
5
6
7          /data/mongodbtest/mongodb-linux-x86_64-2
8          .4.8
9          /bin/mongod
10           --shardsvr --replSet shard1 --port 22001 --dbpath 
11          /data/mongodbtest/shard1/data 
12           --logpath 
13          /data/mongodbtest/shard1/log/shard1
14          .log --fork --nojournal  --oplogSize 10
15

为了快速启动并节约测试环境存储空间,这里加上 nojournal 是为了关闭日志信息,在我们的测试环境不需要初始化这么大的redo日志。同样设置 oplogsize是为了降低 local 文件的大小,oplog是一个固定长度的 capped collection,它存在于”local”数据库中,用于记录Replica Sets操作日志。注意,这里的设置是为了测试!


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1#在每个机器里分别设置分片2服务器及副本集shard2
2        
3
4        
5
6
7          /data/mongodbtest/mongodb-linux-x86_64-2
8          .4.8
9          /bin/mongod
10           --shardsvr --replSet shard2 --port 22002 --dbpath 
11          /data/mongodbtest/shard2/data 
12           --logpath 
13          /data/mongodbtest/shard2/log/shard2
14          .log --fork --nojournal  --oplogSize 10
15

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1#在每个机器里分别设置分片3服务器及副本集shard3
2        
3
4        
5
6
7          /data/mongodbtest/mongodb-linux-x86_64-2
8          .4.8
9          /bin/mongod
10           --shardsvr --replSet shard3 --port 22003 --dbpath 
11          /data/mongodbtest/shard3/data 
12           --logpath 
13          /data/mongodbtest/shard3/log/shard3
14          .log --fork --nojournal  --oplogSize 10
15

分别对每个分片配置副本集,深入了解副本集参考本系列前几篇文章。

任意登陆一个机器,比如登陆192.168.0.136,连接mongodb


1
2
3
4
5
6
7
8
9
10
11
1#设置第一个分片副本集
2        
3
4        
5
6
7          /data/mongodbtest/mongodb-linux-x86_64-2
8          .4.8
9          /bin/mongo 
10           127.0.0.1:22001
11

1
2
3
4
5
6
7
8
1#使用admin数据库
2        
3
4        
5
6
7          use admin
8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
1#定义副本集配置
2        
3
4        
5
6
7          config = { _id:
8          "shard1"
9          , members:[
10        
11
12        
13
14
15                               
16          {_id:0,host:
17          "192.168.0.136:22001"
18          },
19        
20
21        
22
23
24                               
25          {_id:1,host:
26          "192.168.0.137:22001"
27          },
28        
29
30        
31
32
33                               
34          {_id:2,host:
35          "192.168.0.138:22001"
36          ,arbiterOnly:
37          true
38          }
39        
40
41        
42
43
44                          
45          ]
46        
47
48        
49
50
51                   
52          }
53

1
2
3
4
5
6
7
8
1#初始化副本集配置
2        
3
4        
5
6
7          rs.initiate(config);
8

1
2
3
4
5
6
7
8
9
10
11
1#设置第二个分片副本集
2        
3
4        
5
6
7          /data/mongodbtest/mongodb-linux-x86_64-2
8          .4.8
9          /bin/mongo 
10           127.0.0.1:22002
11

1
2
3
4
5
6
7
8
1#使用admin数据库
2        
3
4        
5
6
7          use admin
8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
1#定义副本集配置
2        
3
4        
5
6
7          config = { _id:
8          "shard2"
9          , members:[
10        
11
12        
13
14
15                               
16          {_id:0,host:
17          "192.168.0.136:22002"
18          },
19        
20
21        
22
23
24                               
25          {_id:1,host:
26          "192.168.0.137:22002"
27          },
28        
29
30        
31
32
33                               
34          {_id:2,host:
35          "192.168.0.138:22002"
36          ,arbiterOnly:
37          true
38          }
39        
40
41        
42
43
44                          
45          ]
46        
47
48        
49
50
51                   
52          }
53

1
2
3
4
5
6
7
8
1#初始化副本集配置
2        
3
4        
5
6
7          rs.initiate(config);
8

1
2
3
4
5
6
7
8
9
10
11
1#设置第三个分片副本集
2        
3
4        
5
6
7          /data/mongodbtest/mongodb-linux-x86_64-2
8          .4.8
9          /bin/mongo   
10           127.0.0.1:22003
11

1
2
3
4
5
6
7
8
1#使用admin数据库
2        
3
4        
5
6
7          use admin
8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
1#定义副本集配置
2        
3
4        
5
6
7          config = { _id:
8          "shard3"
9          , members:[
10        
11
12        
13
14
15                               
16          {_id:0,host:
17          "192.168.0.136:22003"
18          },
19        
20
21        
22
23
24                               
25          {_id:1,host:
26          "192.168.0.137:22003"
27          },
28        
29
30        
31
32
33                               
34          {_id:2,host:
35          "192.168.0.138:22003"
36          ,arbiterOnly:
37          true
38          }
39        
40
41        
42
43
44                          
45          ]
46        
47
48        
49
50
51                   
52          }
53

1
2
3
4
5
6
7
8
1#初始化副本集配置
2        
3
4        
5
6
7          rs.initiate(config);
8
  • 9、目前搭建了mongodb配置服务器、路由服务器,各个分片服务器,不过应用程序连接到 mongos 路由服务器并不能使用分片机制,还需要在程序里设置分片配置,让分片生效。


1
2
3
4
5
6
7
8
9
10
11
1#连接到mongos
2        
3
4        
5
6
7          /data/mongodbtest/mongodb-linux-x86_64-2
8          .4.8
9          /bin/mongo 
10           127.0.0.1:20000
11

1
2
3
4
5
6
7
8
1#使用admin数据库
2        
3
4        
5
6
7          user  admin
8

1
2
3
4
5
6
7
8
9
10
1#串联路由服务器与分配副本集1
2        
3
4        
5
6
7          db.runCommand( { addshard : 
8          "shard1/192.168.0.136:22001,192.168.0.137:22001,192.168.0.138:22001"
9          });
10

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


1
2
3
4
5
6
7
8
9
10
1#串联路由服务器与分配副本集2
2        
3
4        
5
6
7          db.runCommand( { addshard : 
8          "shard2/192.168.0.136:22002,192.168.0.137:22002,192.168.0.138:22002"
9          });
10

1
2
3
4
5
6
7
8
9
10
1#串联路由服务器与分配副本集3
2        
3
4        
5
6
7          db.runCommand( { addshard : 
8          "shard3/192.168.0.136:22003,192.168.0.137:22003,192.168.0.138:22003"
9          });
10

1
2
3
4
5
6
7
8
1#查看分片服务器的配置
2        
3
4        
5
6
7          db.runCommand( { listshards : 1 } );
8

#内容输出


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
1{
2        
3
4        
5
6
7                   
8          "shards" : [
9        
10
11        
12
13
14                          
15          {
16        
17
18        
19
20
21                                  
22          "_id" : "shard1",
23        
24
25        
26
27
28                                  
29          "host" : "shard1/192.168.0.136:22001,192.168.0.137:22001"
30        
31
32        
33
34
35                          
36          },
37        
38
39        
40
41
42                          
43          {
44        
45
46        
47
48
49                                  
50          "_id" : "shard2",
51        
52
53        
54
55
56                                  
57          "host" : "shard2/192.168.0.136:22002,192.168.0.137:22002"
58        
59
60        
61
62
63                          
64          },
65        
66
67        
68
69
70                          
71          {
72        
73
74        
75
76
77                                  
78          "_id" : "shard3",
79        
80
81        
82
83
84                                  
85          "host" : "shard3/192.168.0.136:22003,192.168.0.137:22003"
86        
87
88        
89
90
91                          
92          }
93        
94
95        
96
97
98                  
99          ],
100        
101
102        
103
104
105                  
106          "ok" : 1
107        
108
109        
110
111
112          }
113

因为192.168.0.138是每个分片副本集的仲裁节点,所以在上面结果没有列出来。

  • 10、目前配置服务、路由服务、分片服务、副本集服务都已经串联起来了,但我们的目的是希望插入数据,数据能够自动分片,就差那么一点点,一点点。。。

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


1
2
3
4
5
6
7
8
9
10
1#指定testdb分片生效
2        
3
4        
5
6
7          db.runCommand( { enablesharding :
8          "testdb"
9          });
10

1
2
3
4
5
6
7
8
9
10
11
12
1#指定数据库里需要分片的集合和片键
2        
3
4        
5
6
7          db.runCommand( { shardcollection : 
8          "testdb.table1"
9          ,key : {
10          id
11          : 1} } )
12

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

  • 11、测试分片配置结果。


1
2
3
4
5
6
7
8
9
10
11
1#连接mongos服务器
2        
3
4        
5
6
7          /data/mongodbtest/mongodb-linux-x86_64-2
8          .4.8
9          /bin/mongo 
10           127.0.0.1:20000
11

1
2
3
4
5
6
7
8
1#使用testdb
2        
3
4        
5
6
7          use  testdb;
8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1#插入测试数据
2        
3
4        
5
6
7          for
8           (var i = 1; i <= 100000; i++)
9        
10
11        
12
13
14          db.table1.save({
15          id
16          :i,
17          "test1"
18          :
19          "testval1"
20          });
21

1
2
3
4
5
6
7
8
1#查看分片情况如下,部分无关信息省掉了
2        
3
4        
5
6
7          db.table1.stats();
8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
1{
2        
3
4        
5
6
7                  
8          "sharded"
9           : 
10          true
11          ,
12        
13
14        
15
16
17                  
18          "ns"
19           : 
20          "testdb.table1"
21          ,
22        
23
24        
25
26
27                  
28          "count"
29           : 
30          100000
31          ,
32        
33
34        
35
36
37                  
38          "numExtents"
39           : 
40          13
41          ,
42        
43
44        
45
46
47                  
48          "size"
49           : 
50          5600000
51          ,
52        
53
54        
55
56
57                  
58          "storageSize"
59           : 
60          22372352
61          ,
62        
63
64        
65
66
67                  
68          "totalIndexSize"
69           : 
70          6213760
71          ,
72        
73
74        
75
76
77                  
78          "indexSizes"
79           : {
80        
81
82        
83
84
85                          
86          "_id_"
87           : 
88          3335808
89          ,
90        
91
92        
93
94
95                          
96          "id_1"
97           : 
98          2877952
99        
100
101        
102
103
104                  
105          },
106        
107
108        
109
110
111                  
112          "avgObjSize"
113           : 
114          56
115          ,
116        
117
118        
119
120
121                  
122          "nindexes"
123           : 
124          2
125          ,
126        
127
128        
129
130
131                  
132          "nchunks"
133           : 
134          3
135          ,
136        
137
138        
139
140
141                  
142          "shards"
143           : {
144        
145
146        
147
148
149                          
150          "shard1"
151           : {
152        
153
154        
155
156
157                                  
158          "ns"
159           : 
160          "testdb.table1"
161          ,
162        
163
164        
165
166
167                                  
168          "count"
169           : 
170          42183
171          ,
172        
173
174        
175
176
177                                  
178          "size"
179           : 
180          0
181          ,
182        
183
184        
185
186
187                                  
188          ...
189        
190
191        
192
193
194                                  
195          "ok"
196           : 
197          1
198        
199
200        
201
202
203                          
204          },
205        
206
207        
208
209
210                          
211          "shard2"
212           : {
213        
214
215        
216
217
218                                  
219          "ns"
220           : 
221          "testdb.table1"
222          ,
223        
224
225        
226
227
228                                  
229          "count"
230           : 
231          38937
232          ,
233        
234
235        
236
237
238                                  
239          "size"
240           : 
241          2180472
242          ,
243        
244
245        
246
247
248                                  
249          ...
250        
251
252        
253
254
255                                  
256          "ok"
257           : 
258          1
259        
260
261        
262
263
264                          
265          },
266        
267
268        
269
270
271                          
272          "shard3"
273           : {
274        
275
276        
277
278
279                                  
280          "ns"
281           : 
282          "testdb.table1"
283          ,
284        
285
286        
287
288
289                                  
290          "count"
291           :
292          18880
293          ,
294        
295
296        
297
298
299                                  
300          "size"
301           : 
302          3419528
303          ,
304        
305
306        
307
308
309                                  
310          ...
311        
312
313        
314
315
316                                  
317          "ok"
318           : 
319          1
320        
321
322        
323
324
325                          
326          }
327        
328
329        
330
331
332                  
333          },
334        
335
336        
337
338
339                  
340          "ok"
341           : 
342          1
343        
344
345        
346
347
348          }
349

可以看到数据分到3个分片,各自分片数量为: shard1 “count” : 42183,shard2 “count” : 38937,shard3 “count” : 18880。已经成功了!不过分的好像不是很均匀,所以这个分片还是很有讲究的,后续再深入讨论。

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
1public
2           class
3           TestMongoDBShards {
4        
5
6        
7
8
9            
10        
11
12        
13
14
15                 
16          public
17           static
18           void
19           main(String[] args) {
20        
21
22        
23
24
25            
26        
27
28        
29
30
31                       
32          try
33           {
34        
35
36        
37
38
39                            
40          List<ServerAddress> addresses = 
41          new
42           ArrayList<ServerAddress>();
43        
44
45        
46
47
48                            
49          ServerAddress address1 = 
50          new
51           ServerAddress(
52          "192.168.0.136"
53           , 
54          20000
55          );
56        
57
58        
59
60
61                            
62          ServerAddress address2 = 
63          new
64           ServerAddress(
65          "192.168.0.137"
66           , 
67          20000
68          );
69        
70
71        
72
73
74                            
75          ServerAddress address3 = 
76          new
77           ServerAddress(
78          "192.168.0.138"
79           , 
80          20000
81          );
82        
83
84        
85
86
87                            
88          addresses.add(address1);
89        
90
91        
92
93
94                            
95          addresses.add(address2);
96        
97
98        
99
100
101                            
102          addresses.add(address3);
103        
104
105        
106
107
108            
109        
110
111        
112
113
114                            
115          MongoClient client = 
116          new
117           MongoClient(addresses);
118        
119
120        
121
122
123                            
124          DB db = client.getDB( 
125          "testdb"
126           );
127        
128
129        
130
131
132                            
133          DBCollection coll = db.getCollection( 
134          "table1"
135           );
136        
137
138        
139
140
141            
142        
143
144        
145
146
147                            
148          BasicDBObject object = 
149          new
150           BasicDBObject();
151        
152
153        
154
155
156                            
157          object.append( 
158          "id"
159           , 
160          1
161          );
162        
163
164        
165
166
167            
168        
169
170        
171
172
173                            
174          DBObject dbObject = coll.findOne(object);
175        
176
177        
178
179
180            
181        
182
183        
184
185
186                            
187          System. out .println(dbObject);
188        
189
190        
191
192
193            
194        
195
196        
197
198
199                      
200          } 
201          catch
202           (Exception e) {
203        
204
205        
206
207
208                            
209          e.printStackTrace();
210        
211
212        
213
214
215                      
216          }
217        
218
219        
220
221
222                
223          }
224        
225
226        
227
228
229          }
230

整个分片集群搭建完了,思考一下我们这个架构是不是足够好呢?其实还有很多地方需要优化,比如我们把所有的仲裁节点放在一台机器,其余两台机器承担了全部读写操作,但是作为仲裁的192.168.0.138相当空闲。让机器3 192.168.0.138多分担点责任吧!架构可以这样调整,把机器的负载分的更加均衡一点,每个机器既可以作为主节点、副本节点、仲裁节点,这样压力就会均衡很多了,如图:

当然生产环境的数据远远大于当前的测试数据,大规模数据应用情况下我们不可能把全部的节点像这样部署,硬件瓶颈是硬伤,只能扩展机器。要用好mongodb还有很多机制需要调整,不过通过这个东东我们可以快速实现高可用性、高扩展性,所以它还是一个非常不错的Nosql组件。

再看看我们使用的mongodb java 驱动客户端 MongoClient(addresses),这个可以传入多个mongos 的地址作为mongodb集群的入口,并且可以实现自动故障转移,但是负载均衡做的好不好呢?打开源代码查看:

它的机制是选择一个ping 最快的机器来作为所有请求的入口,如果这台机器挂掉会使用下一台机器。那这样。。。。肯定是不行的!万一出现双十一这样的情况所有请求集中发送到这一台机器,这台机器很有可能挂掉。一但挂掉了,按照它的机制会转移请求到下台机器,但是这个压力总量还是没有减少啊!下一台还是可能崩溃,所以这个架构还有漏洞!不过这个文章已经太长了,后续解决吧。

参考:
链接地址

给TA打赏
共{{data.count}}人
人已打赏
安全运维

OpenSSH-8.7p1离线升级修复安全漏洞

2021-10-23 10:13:25

安全运维

设计模式的设计原则

2021-12-12 17:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索