mongodb分片集群搭建与水平扩展

机器分布

构建MongoDB Sharding Cluster,需要三种角色:

1、Shard Server:

每个Shard可以是一个mongod实例,也可以是一组mongod实例构成的Replica Set。

mongod 实例, 使用 Replica Sets,确保每个数据节点都具有备份、自动容错转移、自动恢复能力。用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个relica set承担,防止主机单点故障

2、Config Server:

mongod 实例,使用 3 个配置服务器,确保元数据完整性(two-phase commit)。存储了整个 Cluster Metadata,其中包括 chunk 信息。

3、Route Server:

mongos 实例,配合 LVS,实现负载平衡,提高接入性能(high performance)。前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。

ip 应用 备注
10.1.1.81 仲裁节点 ARBITER
10.1.1.185 分片节点 SECONDARY
10.1.80.122 分片节点 PRIMARY

以上每台机器都跑Shard Server/Config Server/Route Server

MongoDB 副本集(Replica Set)是有自动故障恢复功能的主从集群,有一个Primary节点和一个或多个Secondary节点组成。 PRIMARY -- master SECONDARY -- slave

环境

centeros6.3

mongo应用程序3.2.6,二进制版,放置于/data1/mongodb-3.2.6/

需要运行库(看年人情况而定):

yum -y install net-snmp  
ln -s  /usr/lib64/libssl.so.1.0.1e /usr/lib64/libssl.so.6
ln -s  /usr/lib64/libcrypto.so.6 /usr/lib64/libcrypto.so
ln -s  /usr/lib64/libcrypto.so.6 /usr/lib64/libcrypto.so
ln -s  /usr/lib64/libcrypto.so.1.0.1e /usr/lib64/libcrypto.so
ln -s  /usr/lib64/libcrypto.so.1.0.1e /usr/lib64/libcrypto.so.6
ln -s  /usr/lib64/libnetsnmpmibs.so.20.0.0 /usr/lib64/libnetsnmpmibs.so.20
ln -s  /usr/lib64/libnetsnmpmibs.so.20 /usr/lib64/libnetsnmpmibs.so.10
ln -s  /usr/lib64/libnetsnmpagent.so.20 /usr/lib64/libnetsnmpagent.so.10
ln -s   /usr/lib64/libnetsnmphelpers.so.20.0.0  /usr/lib64/libnetsnmphelpers.so.10
ln -s  /usr/lib64/libnetsnmp.so.20 /usr/lib64/libnetsnmp.so.10
ln -s  /usr/lib64/librpm.so.1.0.0 /usr/lib64/librpm-4.4.so
ln -s  /usr/lib64/librpmio.so.1.0.0 /usr/lib64/librpmio-4.4.so
ln -s  /usr/lib64/libsensors.so.4.2.0 /usr/lib64/libsensors.so.3
ln -s  /usr/lib64/perl5/CORE/libperl.so /usr/lib64/libperl.so

数据目录(后续会根据磁盘使用情况,添加分片,让新分片软链到新磁盘):

/data1/mongodb-3.2.6/data/

新建目录:

mkdir -p mydatabase/mongos/log
mkdir -p mydatabase/config/data
mkdir -p mydatabase/config/log
mkdir -p mydatabase/mongos/log
mkdir -p mydatabase/shard1/log
mkdir -p mydatabase/shard1/data
mkdir -p mydatabase/shard2/log
mkdir -p mydatabase/shard2/data
mkdir -p mydatabase/shard3/log
mkdir -p mydatabase/shard3/data

新建用户

useradd mongodb
chown -R mongodb.mongodb mongodb-3.2.6/
su mongodb

布署

参数解析:

dbpath:数据存放目录
logpath:日志存放路径
pidfilepath:进程文件,方便停止mongodb
directoryperdb:为每一个数据库按照数据库名建立文件夹存放
logappend:以追加的方式记录日志
replSet:replica set的名字
bind_ip:mongodb所绑定的ip地址
port:mongodb进程所使用的端口号,默认为27017
oplogSize:mongodb操作日志文件的最大大小。单位为Mb,默认为硬盘剩余空间的5%
fork:以后台方式运行进程
noprealloc:不预先分配存储

配置服务器

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

config server

lang=bash,lines=22,name=start_mongserv.sh
#!/bin/bash

APP_ROOT=/data1/mongodb-3.2.6
CACHEGB=60
PORT=21000
bind_ip=$(ifconfig eth1 | grep "inet addr" | awk '{print $2;}' | cut -f2 -d":")
## 当服务器上应该不只有mongodb时一定要开启限制使用的内存,不然会吃光机器内存
## 指定的是每个分片进程使用的内存,加上就是整体mongodb大概占用的内存了
isWiredTiger=
wiredTiger="--storageEngine wiredTiger --wiredTigerCacheSizeGB $CACHEGB"
dbpath=$APP_ROOT/data/mydatabase/config/data
logpath=$APP_ROOT/data/mydatabase/config/log/config.log

if [ "$isWiredTiger" = "" ];then
    wiredTiger=""
fi

mongod --configsvr --dbpath $dbpath --bind_ip $bind_ip $wiredTiger --port $PORT --logpath $logpath --fork

路由服务器

因为官网上说明了路由服务器(mongos)只能配置一1台或三台。

--configdb ,<:port>, Set this option to specify a configuration database (i.e. config database) for the sharded cluster. You must specify either 1 configuration server or 3 configuration servers, in a comma separated list.

在选择的服务器分别启动mongos服务器

lang=bash,lines=22,name=start_mongos.sh
#!/bin/bash

APP_ROOT=/data1/mongodb-3.2.6
PORT=20000
bind_ip=$(ifconfig eth1 | grep "inet addr" | awk '{print $2;}' | cut -f2 -d":")
bind_ip=$bind_ip,127.0.0.1
dbpath=$APP_ROOT/data/mydatabase/config/data
logpath=$APP_ROOT/data/mydatabase/mongos/log/mongos.log

# 必须是1个或则3个配置 。
clusterIpStr="10.1.81.22:21000,10.1.80.122:21000,10.1.1.81:21000"

mongos --configdb $clusterIpStr --bind_ip $bind_ip --port $PORT --logpath $logpath --fork

分片服务器

目前搭建三个分片,在三台机器上配置各个分片的副本集

使用sh start_shard [1|2|3]启动

lang=bash,lines=22,name=start_shard.sh
#!/bin/bash

APP_ROOT=/data1/mongodb-3.2.6
CACHEGB=60
bind_ip=$(ifconfig eth1 | grep "inet addr" | awk '{print $2;}' | cut -f2 -d":")
bind_ip=$bind_ip,127.0.0.1

#journal="--journal"
journal="--nojournal"
oplog="--oplogSize 10"
isWiredTiger=
wiredTiger="--storageEngine wiredTiger --wiredTigerCacheSizeGB $CACHEGB"

if [ "$isWiredTiger" = "" ];then
    wiredTiger=""
fi

INDEX=$1
if [ -z $1 ];then
    INDEX=1
fi
mongod --shardsvr --replSet shard${INDEX} --bind_ip $bind_ip --port 2200${INDEX} $wiredTiger --dbpath ${APP_ROOT}/data/mydatabase/shard${INDEX}/data  --logpath ${APP_ROOT}/data/mydatabase/shard${INDEX}/log/shard${INDEX}.log --fork $journal  $oplog

配置主,备,仲裁节点

分别对每个分片服务器上面配置, 更换下面的ip端口分别执行三次

"_id": 副本集的名称 "members": 副本集的服务器列表 "_id": 服务器的唯一ID "host": 服务器主机 "priority": 是优先级,默认为1,优先级0为被动节点,不能成为活跃节点。优先级不位0则按照有大到小选出活跃节点。 "arbiterOnly": 仲裁节点,只参与投票,不接收数据,也不能成为活跃节点。

~$mongod 10.1.80.122:22001

#使用admin数据库
use admin
#定义副本集配置
config = { _id:"shard1", members:[
                     {_id:0,host:"10.1.80.122:22001"},
                     {_id:1,host:"10.1.1.185:22001"},
                     {_id:2,host:"10.1.1.81:22001",arbiterOnly:true}
                ]
         }
#初始化副本集配置
rs.initiate(config);

配置Sharding

目前搭建了mongodb配置服务器、路由服务器,各个分片服务器,不过应用程序连接到 mongos 路由服务器并不能使用分片机制,还需要在程序里设置分片配置,让分片生效。

连接上配置mongos, 配置副本集:

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

#使用admin数据库
user  admin
#串联路由服务器与分配副本集1
db.runCommand( { addshard : "shard1/10.1.80.122:22001,10.1.1.185:22001,10.1.1.81:22001"});
db.runCommand( { addshard : "shard2/10.1.80.122:22002,10.1.1.185:22002,10.1.1.81:22002"});
db.runCommand( { addshard : "shard3/10.1.80.122:22003,10.1.1.185:22003,10.1.1.81:22003"});
#查看分片服务器的配置
db.runCommand( { listshards : 1 } );

配置库与集合进行分片

目前配置服务、路由服务、分片服务、副本集服务都已经串联起来了,但我们的目的是希望插入数据,数据能够自动分片.

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

#指定testdb分片生效
db.runCommand( { enablesharding :"mydatabase"});
#指定数据库里需要分片的集合和片键
db.runCommand( { shardcollection : "mydatabase.my_table",key : {start: 1} } )
# 查看分片信息
db.printShardingStatus()
# 分片分布
db.recover_gateway.getShardDistribution()

添加分片

IMPORTANT: 在副本集的环境中,要是所有的Secondary都宕机了,只剩下Primary。最后Primary会变成Secondary,不能提供服务。

NOTE: 所以当三个shard,任意进程down了,都不能再正常录入/读取数据了

测试添加一个备份点 --- 这里只是测试

现在有另一台机器

ip 说明
10.1.81.22 分片节点

以shard2举例, 查看shard2的副本配置

MongoDB Enterprise shard2:PRIMARY> cfg=rs.conf()
{
        "_id" : "shard2",
        "version" : 1,
        "protocolVersion" : NumberLong(1),
        "members" : [
                {
                        "_id" : 0,
                        "host" : "10.1.80.122:22002",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 1,
                        "host" : "10.1.1.185:22002",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 2,
                        "host" : "10.1.1.81:22002",
                        "arbiterOnly" : true,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                }
        ],
        "settings" : {
                "chainingAllowed" : true,
                "heartbeatIntervalMillis" : 2000,
                "heartbeatTimeoutSecs" : 10,
                "electionTimeoutMillis" : 10000,
                "getLastErrorModes" : {

                },
                "getLastErrorDefaults" : {
                        "w" : 1,
                        "wtimeout" : 0
                },
                "replicaSetId" : ObjectId("587b8f52c194362b6149ac3c")
        }
}
ip 说明 应用
10.1.1.81 仲裁节点 ARBITER
10.1.1.185 分片节点 SECONDARY
10.1.80.122 分片节点 PRIMARY

现在添加另一个SECONDARY 到shard2中

MongoDB Enterprise shard2:PRIMARY> rs.add("10.1.81.22:22002")
{ "ok" : 1 }
MongoDB Enterprise shard2:PRIMARY> rs.status()
{
        "set" : "shard2",
        "date" : ISODate("2017-01-18T09:20:01.947Z"),
        "myState" : 1,
        "term" : NumberLong(3),
        "heartbeatIntervalMillis" : NumberLong(2000),
        "members" : [
                {
.... 此如略很多
                {
                        "_id" : 3,
                        "name" : "10.1.81.22:22002",
                        "health" : 1,
                        "state" : 5,
                        "stateStr" : "STARTUP2", ###这个时候正在同步数据,可查看新的目录大小,最后变成SECONDARY
                        "uptime" : 19,
                        "optime" : {
                                "ts" : Timestamp(0, 0),
                                "t" : NumberLong(-1)
                        },
                        "optimeDate" : ISODate("1970-01-01T00:00:00Z"),
                        "lastHeartbeat" : ISODate("2017-01-18T09:20:00.918Z"),
                        "lastHeartbeatRecv" : ISODate("2017-01-18T09:20:00.950Z"),
                        "pingMs" : NumberLong(0),
                        "syncingTo" : "10.1.80.122:22002",
                        "configVersion" : 2
                }

stateStr状态列表如下:

  1. STARTUP:刚加入到复制集中,配置还未加载
  2. STARTUP2:配置已加载完,初始化状态
  3. RECOVERING:正在恢复,不适用读
  4. ARBITER: 仲裁者
  5. DOWN:节点不可到达
  6. UNKNOWN:未获取其他节点状态而不知是什么状态,一般发生在只有两个成员的架构,脑裂
  7. REMOVED:移除复制集
  8. ROLLBACK:数据回滚,在回滚结束时,转移到RECOVERING或SECONDARY状态
  9. FATAL:出错。查看日志grep “replSet FATAL”找出错原因,重新做同步
  10. PRIMARY:主节点
  11. SECONDARY:备份节点

IMPORTANT:这时就可以保证,当PRIMARY关闭时,两个SECONDARY会选举其中之一做为PRIMARY

IMPORTANT:可以通过这样切换机器之间的主结点

测试删除

手动切换Primary节点到自己给定的节点:把给定的服务器的priority加到最大即可

MongoDB Enterprise shard2:PRIMARY> cfg.members[2].priority=2  #修改priority
MongoDB Enterprise shard2:PRIMARY> rs.reconfig(cfg) #重新加载配置文件,强制了副本集进行一次选举,优先级高的成为Primary。在这之间整个集群的所有节点都是secondary

添加分片,即添加一个副本集到mongos中

因为在设置mongos已经确定了集群配置的机器ip,所以如果要达到跨机器容灾分片,也只能是添加那些运行在这些机器ip上的副本集。

垂直扩展

以shard4为例子

一、 准备好新的副本集

在以下三台机器上面启动新的副本集进程,端口为22004

ip 说明 应用
10.1.1.81 仲裁节点 ARBITER
10.1.1.185 分片节点 SECONDARY
10.1.80.122 分片节点 PRIMARY
mkdir -p data/mydatabase/shard4/data
mkdir -p data/mydatabase/shard4/log

# 分别开启进程
sh start_shard.sh 4

二、 添加到分片中

## 连接上mongos
#使用admin数据库
use admin
#定义副本集配置
config = { _id:"shard4", members:[
                     {_id:0,host:"10.1.80.122:22004"},
                     {_id:1,host:"10.1.1.185:22004"},
                     {_id:2,host:"10.1.1.81:22004",arbiterOnly:true}
                ]
         }
#初始化副本集配置
rs.initiate(config);

# 添加
db.runCommand( { addshard : "shard4/10.1.80.122:22004,10.1.1.185:22004,10.1.1.81:22004"});

水平扩展

即添加另一台机器到分片集群当中

ip 说明
10.1.81.22 分片节点

WARNING:正如上面所说,不能达到跨机器的容灾,只能通过在这台机器上新建副本集达到。

一、新建副本集

arbiter/primary/secondary三个进程结点,分别用不同端口开始

lang=bash,lines=29,name=start_shard22_1.sh
mongod --shardsvr --replSet shard22_1  --bind_ip 10.1.81.22,127.0.0.1 --port 32001 --dbpath /data2/mongodb_data/data/arbiter  --logpath /data2/mongodb_data/log/shard22_1/arbiter.log --fork --nojournal  --oplogSize 1000
mongod --shardsvr --replSet shard22_1  --bind_ip 10.1.81.22,127.0.0.1 --port 32002 --dbpath /data2/mongodb_data/data/primary  --logpath /data2/mongodb_data/log/shard22_1/primary.log --fork --nojournal  --oplogSize 1000
mongod --shardsvr --replSet shard22_1  --bind_ip 10.1.81.22,127.0.0.1 --port 32003 --dbpath /data2/mongodb_data/data/secondary  --logpath /data2/mongodb_data/log/shard22_1/secondary.log --fork --nojournal  --oplogSize 1000

登录主结点

#使用admin数据库
use admin
#定义副本集配置
config = { _id:"shard22_1", members:[
                     {_id:0,host:"10.1.81.22:32003"},
                     {_id:1,host:"10.1.81.22:32002", priority: 2},
                     {_id:2,host:"10.1.81.22:32001",arbiterOnly:true}
                ]
         }
#初始化副本集配置
rs.initiate(config);

再查看信息, 完全符合我们的要求

MongoDB Enterprise shard22_1:PRIMARY> rs.status()
{
        "set" : "shard22_1",
        "date" : ISODate("2017-01-19T03:36:28.543Z"),
        "myState" : 1,
        "term" : NumberLong(1),
        "heartbeatIntervalMillis" : NumberLong(2000),
        "members" : [
                {
                        "_id" : 0,
                        "name" : "10.1.81.22:32003",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 14,
                        "optime" : {
                                "ts" : Timestamp(1484796973, 1),
                                "t" : NumberLong(-1)
                        },
                        "optimeDate" : ISODate("2017-01-19T03:36:13Z"),
                        "lastHeartbeat" : ISODate("2017-01-19T03:36:26.611Z"),
                        "lastHeartbeatRecv" : ISODate("2017-01-19T03:36:27.914Z"),
                        "pingMs" : NumberLong(0),
                        "configVersion" : 1
                },
                {
                        "_id" : 1,
                        "name" : "10.1.81.22:32002",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 160,
                        "optime" : {
                                "ts" : Timestamp(1484796984, 2),
                                "t" : NumberLong(1)
                        },
                        "optimeDate" : ISODate("2017-01-19T03:36:24Z"),
                        "infoMessage" : "could not find member to sync from",
                        "electionTime" : Timestamp(1484796984, 1),
                        "electionDate" : ISODate("2017-01-19T03:36:24Z"),
                        "configVersion" : 1,
                        "self" : true
                },
                {
                        "_id" : 2,
                        "name" : "10.1.81.22:32001",
                        "health" : 1,
                        "state" : 7,
                        "stateStr" : "ARBITER",
                        "uptime" : 14,
                        "lastHeartbeat" : ISODate("2017-01-19T03:36:26.611Z"),
                        "lastHeartbeatRecv" : ISODate("2017-01-19T03:36:25.911Z"),
                        "pingMs" : NumberLong(0),
                        "configVersion" : 1
                }
        ],
        "ok" : 1
}

二、添加到分片集群中

在集群的mongos中

#使用admin数据库
user  admin
#串联路由服务器与分配副本集1
db.runCommand( { addshard : "shard22_1/10.1.81.22:32001,10.1.81.22:32002,10.1.81.22:32003"});
db.runCommand( { listshards : 1 } );
MongoDB Enterprise mongos> db.runCommand( { listshards : 1 } );
{
        "shards" : [
                {
                        "_id" : "shard1",
                        "host" : "shard1/10.1.1.185:22001,10.1.80.122:22001"
                },
                {
                        "_id" : "shard2",
                        "host" : "shard2/10.1.1.185:22002,10.1.80.122:22002,10.1.81.22:22002"
                },
                {
                        "_id" : "shard3",
                        "host" : "shard3/10.1.1.185:22003,10.1.80.122:22003"
                },
                {
                        "_id" : "shard22_1",
                        "host" : "shard22_1/10.1.81.22:32002,10.1.81.22:32003"  ## 多了一个副本集
                }
        ],
        "ok" : 1
}

## 表分片配置没有查到添加的新分片,但是整体分片信息查到有

MongoDB Enterprise mongos> db.my_table.getShardDistribution()

Shard shard1 at shard1/10.1.1.185:22001,10.1.80.122:22001
 data : 6.6GiB docs : 10647955 chunks : 177
 estimated data per chunk : 38.22MiB
 estimated docs per chunk : 60157

Shard shard2 at shard2/10.1.1.185:22002,10.1.80.122:22002,10.1.81.22:22002
 data : 6.7GiB docs : 10800351 chunks : 178
 estimated data per chunk : 38.56MiB
 estimated docs per chunk : 60676

Shard shard3 at shard3/10.1.1.185:22003,10.1.80.122:22003
 data : 6.61GiB docs : 10655688 chunks : 177
 estimated data per chunk : 38.25MiB
 estimated docs per chunk : 60201

Totals
 data : 19.92GiB docs : 32103994 chunks : 532
 Shard shard1 contains 33.16% data, 33.16% docs in cluster, avg obj size on shard : 666B
 Shard shard2 contains 33.64% data, 33.64% docs in cluster, avg obj size on shard : 666B
 Shard shard3 contains 33.19% data, 33.19% docs in cluster, avg obj size on shard : 666B

## 发现数据在不断往新分片机器blance

MongoDB Enterprise mongos> db.printShardingStatus()
--- Sharding Status --- 
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("587b8cb62a42fb5cf9aa6f5b")
}
  shards:
        {  "_id" : "shard1",  "host" : "shard1/10.1.1.185:22001,10.1.80.122:22001" }
        {  "_id" : "shard2",  "host" : "shard2/10.1.1.185:22002,10.1.80.122:22002,10.1.81.22:22002" }
        {  "_id" : "shard22_1",  "host" : "shard22_1/10.1.81.22:32002,10.1.81.22:32003" }
        {  "_id" : "shard3",  "host" : "shard3/10.1.1.185:22003,10.1.80.122:22003" }
  active mongoses:
        "3.2.6" : 3
  balancer:
        Currently enabled:  yes
        Currently running:  yes
                Balancer lock taken at Thu Jan 19 2017 11:46:45 GMT+0800 (CST) by namenode:20000:1484491991:1073590005:Balancer:329466923
        Collections with active migrations: 
                mydatabase.my_table started at Thu Jan 19 2017 11:46:45 GMT+0800 (CST)
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours: 
                105 : Success
  databases:
        {  "_id" : "mydatabase",  "primary" : "shard2",  "partitioned" : true }
                mydatabase.my_table
                        shard key: { "start" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard1  176
                                shard2  176
                                shard22_1       7
                                shard3  176
                        too many chunks to print, use verbose if you want to force print

从上面数据可以看出,表my_table并没有分片到shard22_1这个副本集中!!!

但是,在shard22_1主结点上面查看,数据能在这个副本集中查到

MongoDB Enterprise shard22_1:PRIMARY> use mydatabase
switched to db mydatabase
MongoDB Enterprise shard22_1:PRIMARY> show tables;
my_table
MongoDB Enterprise shard22_1:PRIMARY>  db.my_table.getShardDistribution()
Collection mydatabase.my_table is not sharded.
MongoDB Enterprise shard22_1:PRIMARY> db.my_table.findOne()
{
        "_id" : ObjectId("587b9dad0da2b88ce6a53698"),
        "start" : 1484496239,
        "end" : 1484496239,
... 略

最后集群

|ip|应用|备注| |10.1.1.81|仲裁节点|shard1,shard2,shar3; 跨机副本集| |10.1.1.185|分片节点|shard1,shard2,shar3; 跨机副本集| |10.1.80.122|分片节点|shard1,shard2,shar3; 跨机副本集| |10.1.81.22|分片节点|shard22_1,单机副本集|

不管你的分片集群环境的数据架构如何,一定要确保所有操作都通过mongos 路由到分片上。即使你的操作针对的是未分片的数据,影响不了分片数据,也要通过mongos 来路由。

调整计划

1、把10.1.80.122 这个主结点的三个分片,切到10.1.81.22上来

2、把路由修改为10.1.1.81、10.1.80.122、10.1.81.22

后面继续