余晖落尽暮晚霞,黄昏迟暮远山寻
本站
当前位置:网站首页 > 编程知识 > 正文

新一代Java程序员必学的Docker容器化技术基础篇

xiyangw 2023-05-13 16:20 10 浏览 0 评论

概述

定义

MongoDB官网** https://www.mongodb.com/ 社区版最新版本5.0,其中5.2版本很快也要面世了**

MongoDB GitHub源码** https://github.com/mongodb **

新一代Java程序员必学的Docker容器化技术基础篇

MongoDB文档地址** **https://docs.mongodb.com/manual/

MongoDB是一个流行的开源分布式文档型数据库,由 C++ 语言编写,旨在处理大规模额数据,为 WEB 应用提供可扩展、高性能的数据存储解决方案。

MongoDB介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。前面我们学习了MySQL和Elasticsearch,我们本篇后续章节也会学习和聊聊MongoDB与这两者的故事。

特性

  • 面向文档存储,MongoDB从存储结构上使用类似json的bjson格式,这就比关系型数据库MySQL存储更灵活些,不需要先定义表结构也让DDL管理更加简单,文档式结构也更容易理解;动态 DDL能力,没有强Schema约束也让DDL管理更加简单,支持更快速迭代。
  • 完全分布式、高可用,高性能计算,提供基于内存的快速数据查询。
  • 容易扩展,利用数据分片可以支持海量数据存储,实现自动分片和水平扩展。
  • 丰富的功能集,支持二级索引、强大的聚合管道功能、事务、join,为开发者量身定做的功能,如数据自动老化、固定集合等等。MongoDB是NoSQL中最像SQL的数据库。
  • 跨平台版本、支持多语言SDK。

bson和json的区别

bson是一种二进制形式的存储格式,采用了相似于C 语言结构体的名称、对表示方法,支持内嵌的文档对象和数组对象,具备轻量性、可遍历性、高效性的特色,能够有效描述非结构化数据和结构化数据,有点相似于Google的Protocol Buffer。

  • 更快的遍历速度:对json格式来讲,太大的json结构会导致数据遍历变慢;在json中要跳过一个文档进行数据读取,须要对此文档进行扫描匹配比如括号的匹配,而bson将每个元素的长度存在元素的头部,这样就可快速读到指定位置。
  • 操做更简易:对json来讲数据存储是无类型的,比如你要修改值9为10这样就从一个字符变成了两个字符,也即是后面的内容都要后移一位因此增加开销。而使用bson可以指定这个列为数字类型,那么数字从9改为10甚至是10000,这样都只是在存储数字上修改,不会致使数据总长度变化。当时在MongoDB中若是数字从整形增大到长整型那仍是会致使数据总长度变大的。
  • 增加额外的数据类型:json是一个很方便的数据交换格式,可是其类型比较有限;bson在其基础上增长了“byte array”数据类型,这使得二进制的存储再也不需要先base64转换后再存成json,大大减小了计算开销和数据大小。下图为bson支持数据类型

数据模型与关系型数据库对比

  • database-数据库,与关系型数据库(database)概念相同,一个数据库包含多个集合(表)。
  • collection-集合,相当于关系型数据库中的表(table),一个集合可以存放多个文档(行)。不同之处就在于集合的结构(schema)是动态的,不需要预先声明一个严格的表结构。更重要的是默认情况下MongoDB 并不会对写入的数据做任何schema的校验。
  • document-文档,相当于关系型数据库中的行(row),一个文档由多个字段(列)组成,并采用bson(json)格式表示。
  • field-字段,相当于关系型数据库中的列(column),相比普通column的差别在于field的类型可以更加灵活比如支持嵌套的文档、数组,区分大小写。
  • 其他说明id-主键,MongoDB 默认生成id 字段来保证文档的唯一性。reference-引用,勉强可以对应于外键(foreign key) 的概念,但reference 并没有实现任何外键约束,只是由客户端(driver)自动进行关联查询、转换的一个特殊类型。view-视图,MongoDB 3.4 开始支持视图,这个和关系型数据库的视图没有什么差异,视图是基于集合之上进行动态查询的一层对象,可以是虚拟的,也可以是物理的(物化视图)。index-索引,与关系型数据库的索引相同。$lookup-聚合操作符,可以用于实现类似关系型数据库-join连接的功能。transaction-事务,从 MongoDB 4.0 版本开始,提供了对于事务的支持。aggregation-聚合,MongoDB 提供了强大的聚合计算框架,group by是其中的一类聚合操作。

Elasticsearch与MongoDB对比

  • 相同点存储格式:MongoDB和Elasticsearch都属于json格式NoSQL大家族、文档型数据存储。可用性和容错:MongoDB和ElasticSearch作为天生分布式的代表产品都支持数据分片、和副本、复制,两者都通过分片支持水平扩展, 同时都通过副本来支持高可用分片:一个数据集的数据分为多份, 同时分布在多个节点上存储和管理, 主流分片有hash分片和range分片这两种方式,各有优势, 适合不同的场景。ElasticSearch是hash,Mongo是range和hash。副本:一份数据集同时有一个或者多个复制品(或者叫主从), 每份复制品都一模一样, 但是为了保证数据的一致性, 往往多个副本中只有一个作为Primary副本(通过选主算法从多个副本中选出Primary), 提供写服务, 其他副本只提供读, 或者只提供备份服务。ElasticSearch和MongoDB都可以通过副本增强读能力, 而前面我们学习的kafka的副本是只有备份功能。都支持CRUD操作、聚合、简单版join操作和处理超大规模的数据。MongoDB和ElasticSearch也都支持全文索引, 但是MongoDB的全文索引效果完全无法跟专业的搜索引擎产品ElasticSearch相比,被吊打也是可以理解的。
  • 不同点定位:MongoDB是文档型数据库**, 提供数据存储和管理服务,Elasticsearch 是搜索服务, 提供数据检索服务;MongoDB作为一个数据库产品,是拥有源数据管理能力的,Elasticsearch作为一个搜索引擎, 定位是提供数据检索服务。**读写能力:Elasticsearch 可以从其他数据源同步数据过来提供查询, 但是不适合对数据进行存储和管理,Elasticsearch修改Mapping的代价非常高, 所以我们一般都是把新数据重新写一份新索引,然后直接切换新索引库,Elasticsearch更侧重数据的查询, 各种复杂的花式查询支持的很好。存储引擎:MongoDB支持的存储引擎有WiredTiger和In-Memory;WiredTiger按照b-tree的形式来组织并进行扩展,支持两种基础文件格式:行存储和列存储,其中两者都是键/值存储的B+ tree实现,还支持日志结构的合并树实现也为B+树;In-Memory将数据只存储在内存中。Elasticsearch底层使用lucene全文检索引擎作为核心引擎。部署与资源占用:集群化分片+副本的部署方式, Elasticsearch部署起来比MongoDB方便很多;MongoDB可以支持存储文件类型的数据, 作为数据库也有数据压缩能力, Elasticsearch则因为大量的索引存在需要占用大量的磁盘和内存空间,资源开销较大。分布式方案:MongoDB是以节点为单位划分角色, 一旦一个节点被指定为副本, 其上面的数据都是副本;Elasticsearch是以分片为单位划分角色, 一个节点上即可以拥有某分片的主分片和可以同时拥有另一个分片的副本分片, 同时Elasticsearch还支持自动的副本负载均衡, 如果一个新节点上面什么数据都没有, 系统会自动分配分片数据过来。MongoDB支持事务,Elasticsearch不支持事务。Elasticsearch是Java编写,通过RESTFul接口操作数据。MongoDB是C++编写,通过driver操作数据。Elasticsearch是天生分布式,主副分片自动分配和复制,开箱即用,而MongoDB的要手动配置,且部署分片集群和配置较为麻烦。Elasticsearch偏向于检索、查询和数据分析,适用于OLAP(on-line Analytical Processing)系统,MongoDB偏向于大数据下的CRUD,适用于OLTP(on-line Transaction Processing)系统。从时效性上看,Elasticsearch非实时,有丢数据的风险,而MongoDB是实时,理论上无丢数据的风险。

Elasticsearch和MongoDB适合使用场景

  • MongoDB对服务可用性和一致性有高要求,MongoDB对传统RDBMS造成强有力的竞争威胁。无schema的数据存储+需要索引数据。高读写性能要求, 数据使用场景简单的海量数据场景。有热点数据, 有数据分片需求的数据存储。日志、html、爬虫数据等半结构化或图片,视频等非结构化数据的存储。
  • Elasticsearch起初就是以检索查询为主要应用场景出道,与RDBMS做相互协助。已经有其他系统负责数据管理。对复杂场景下的查询需求,对查询性能有要求, 对写入及时性要求不高的场景。监控信息/日志信息检索。小团队但是有多语言服务,es拥有restful接口,用起来最方便。

分布式集群部署

集群架构

  • Shard:分片服务器**:用于存储实际的数据块,实际生产环境中一个Shard Server角色可由几台机器组成一个replica set副本集承担,防止主机单点故障。**分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程。将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载。基本思想就是将集合切成小块,这些块分散到若干片里,每个片只负责总数据的一部分,最后通过一个均衡器来对各个分片进行均衡(数据迁移)。通过一个名为mongos的路由进程进行操作,mongos知道数据和片的对应关系(通过配置服务器)。大部分使用场景都是解决磁盘空间的问题,对于写入有可能会变差,查询则尽量避免跨分片查询。使用分片的时机机器的磁盘不够用了。使用分片解决磁盘空间的问题。单个mongod已经不能满足写数据的性能要求。通过分片让写压力分散到各个分片上面,使用分片服务器自身的资源。把大量数据放到内存里提高性能,通过分片可以使用到分片服务器自身的资源。
  • Config Server:配置服务器**:mongod实例,存储了整个 分片群集的配置信息,其中包括 chunk信息。**
  • Mongos**:前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用透明化。**

部署规划

前面我们学习了Docker,本篇我们就利用docker-compose来编排部署MongoDB分片集群,那我们就开始练手了

部署一个两个副本集(每个副本集3个节点)、配置服务器集群(3个节点)、一个路由节点

一键部署脚本

当前目录下创建scripts文件夹,创建setup.sh、setup-cnf.sh、init-shard.sh和docker-compose.yml文件。

setup.sh内容如下:

#!/bin/bash 

mongodb1=`getent hosts ${MONGO1} | awk '{ print $1 }'`
mongodb2=`getent hosts ${MONGO2} | awk '{ print $1 }'`
mongodb3=`getent hosts ${MONGO3} | awk '{ print $1 }'`

port=${PORT:-27017}

echo "Waiting for startup.."
until mongo --host ${mongodb1}:${port} --eval 'quit(db.runCommand({ ping: 1 }).ok ? 0 : 2)' &>/dev/null; do
  printf '.'
  sleep 1
done

echo "Started.."

echo setup.sh time now: `date +"%T" `
mongo --host ${mongodb1}:${port} <<EOF
   var cfg = {
        "_id": "${RS}",
        "protocolVersion": 1,
        "members": [
            {
                "_id": 0,
                "host": "${mongodb1}:${port}"
            },
            {
                "_id": 1,
                "host": "${mongodb2}:${port}"
            },
            {
                "_id": 2,
                "host": "${mongodb3}:${port}"
            }
        ]
    };
    rs.initiate(cfg, { force: true });
    rs.reconfig(cfg, { force: true });
EOF

setup-cnf.sh内容如下:

#!/bin/bash 

mongodb1=`getent hosts ${MONGO1} | awk '{ print $1 }'`
mongodb2=`getent hosts ${MONGO2} | awk '{ print $1 }'`
mongodb3=`getent hosts ${MONGO3} | awk '{ print $1 }'`

port=${PORT:-27017}

echo "Waiting for startup.."
until mongo --host ${mongodb1}:${port} --eval 'quit(db.runCommand({ ping: 1 }).ok ? 0 : 2)' &>/dev/null; do
  printf '.'
  sleep 1
done

echo "Started.."

echo setup-cnf.sh time now: `date +"%T" `
mongo --host ${mongodb1}:${port} <<EOF
   var cfg = {
        "_id": "${RS}",
        "configsvr": true,
        "protocolVersion": 1,
        "members": [
            {
                "_id": 100,
                "host": "${mongodb1}:${port}"
            },
            {
                "_id": 101,
                "host": "${mongodb2}:${port}"
            },
            {
                "_id": 102,
                "host": "${mongodb3}:${port}"
            }
        ]
    };
    rs.initiate(cfg, { force: true });
    rs.reconfig(cfg, { force: true });
EOF

init-shard.sh内容如下:

#!/bin/bash 

mongodb1=`getent hosts ${MONGOS} | awk '{ print $1 }'`

mongodb11=`getent hosts ${MONGO11} | awk '{ print $1 }'`
mongodb12=`getent hosts ${MONGO12} | awk '{ print $1 }'`
mongodb13=`getent hosts ${MONGO13} | awk '{ print $1 }'`

mongodb21=`getent hosts ${MONGO21} | awk '{ print $1 }'`
mongodb22=`getent hosts ${MONGO22} | awk '{ print $1 }'`
mongodb23=`getent hosts ${MONGO23} | awk '{ print $1 }'`

mongodb31=`getent hosts ${MONGO31} | awk '{ print $1 }'`
mongodb32=`getent hosts ${MONGO32} | awk '{ print $1 }'`
mongodb33=`getent hosts ${MONGO33} | awk '{ print $1 }'`

port=${PORT:-27017}

echo "Waiting for startup.."
until mongo --host ${mongodb1}:${port} --eval 'quit(db.runCommand({ ping: 1 }).ok ? 0 : 2)' &>/dev/null; do
  printf '.'
  sleep 1
done

echo "Started.."

echo init-shard.sh time now: `date +"%T" `
mongo --host ${mongodb1}:${port} <<EOF
   sh.addShard( "${RS1}/${mongodb11}:${PORT1},${mongodb12}:${PORT2},${mongodb13}:${PORT3}" );
   sh.addShard( "${RS2}/${mongodb21}:${PORT1},${mongodb22}:${PORT2},${mongodb23}:${PORT3}" );
   sh.status();
EOF

docker-compose.yml内容如下:

version: '3.9'
services:
  mongo-1-2:
    container_name: "mongo-1-2"
    image: mongo:5.0.5
    ports:
      - "30012:27017"
    command: mongod --replSet rs1 --shardsvr --port 27017  --oplogSize 16
    restart: always
    networks:
      - mongo

  mongo-1-3:
    container_name: "mongo-1-3"
    image: mongo:5.0.5
    ports:
      - "30013:27017"
    command: mongod --replSet rs1 --shardsvr --port 27017  --oplogSize 16
    restart: always
    networks:
      - mongo

  mongo-1-1:
    container_name: "mongo-1-1"
    image: mongo:5.0.5
    ports:
      - "30011:27017"
    command: mongod --replSet rs1 --shardsvr --port 27017  --oplogSize 16
    restart: always
    networks:
      - mongo

  mongo-rs1-setup:
    container_name: "mongo-rs1-setup"
    image: mongo:5.0.5
    depends_on:
      - "mongo-1-1"
      - "mongo-1-2"
      - "mongo-1-3"
    volumes:
      - ./scripts:/scripts
    environment:
      - MONGO1=mongo-1-1
      - MONGO2=mongo-1-2
      - MONGO3=mongo-1-3
      - RS=rs1
    entrypoint: [ "/scripts/setup.sh" ]
    networks:
      - mongo

  mongo-2-2:
    container_name: "mongo-2-2"
    image: mongo:5.0.5
    ports:
      - "30022:27017"
    command: mongod --replSet rs2 --shardsvr --port 27017  --oplogSize 16
    restart: always
    networks:
      - mongo

  mongo-2-3:
    container_name: "mongo-2-3"
    image: mongo:5.0.5
    ports:
      - "30023:27017"
    command: mongod --replSet rs2 --shardsvr --port 27017  --oplogSize 16
    restart: always
    networks:
      - mongo

  mongo-2-1:
    container_name: "mongo-2-1"
    image: mongo:5.0.5
    ports:
      - "30021:27017"
    command: mongod --replSet rs2 --shardsvr --port 27017  --oplogSize 16
    restart: always
    networks:
      - mongo

  mongo-rs2-setup:
    container_name: "mongo-rs2-setup"
    image: mongo:5.0.5
    depends_on:
      - "mongo-2-1"
      - "mongo-2-2"
      - "mongo-2-3"
    volumes:
      - ./scripts:/scripts
    environment:
      - MONGO1=mongo-2-1
      - MONGO2=mongo-2-2
      - MONGO3=mongo-2-3
      - RS=rs2
    entrypoint: [ "/scripts/setup.sh" ]
    networks:
      - mongo

  mongo-cnf-2:
    container_name: "mongo-cnf-2"
    image: mongo:5.0.5
    ports:
      - "30102:27017"
    command: mongod --replSet cnf-serv --configsvr --port 27017 --oplogSize 16
    restart: always
    networks:
      - mongo

  mongo-cnf-3:
    container_name: "mongo-cnf-3"
    image: mongo:5.0.5
    ports:
      - "30103:27017"
    command: mongod --replSet cnf-serv --configsvr --port 27017 --oplogSize 16
    restart: always
    networks:
      - mongo

  mongo-cnf-1:
    container_name: "mongo-cnf-1"
    image: mongo:5.0.5
    ports:
      - "30101:27017"
    command: mongod --replSet cnf-serv --configsvr --port 27017 --oplogSize 16
    restart: always
    networks:
      - mongo

  mongo-cnf-setup:
    container_name: "mongo-cnf-setup"
    image: mongo:5.0.5
    depends_on:
      - "mongo-cnf-1"
      - "mongo-cnf-2"
      - "mongo-cnf-3"
    volumes:
      - ./scripts:/scripts
    environment:
      - MONGO1=mongo-cnf-1
      - MONGO2=mongo-cnf-2
      - MONGO3=mongo-cnf-3
      - RS=cnf-serv
      - PORT=27017
    entrypoint: [ "/scripts/setup-cnf.sh" ]
    networks:
      - mongo

  mongo-router:
    container_name: "mongo-router"
    image: mongo:5.0.5
    ports:
      - "30001:27017"
    depends_on:
      - "mongo-rs1-setup"
      - "mongo-rs2-setup"
      - "mongo-cnf-setup"
    command: mongos --configdb cnf-serv/mongo-cnf-1:27017,mongo-cnf-2:27017,mongo-cnf-3:27017 --port 27017 --bind_ip 0.0.0.0
    restart: always
    networks:
      - mongo

  mongo-shard-setup:
    container_name: "mongo-shard-setup"
    image: mongo:5.0.5
    depends_on:
      - "mongo-router"
    volumes:
      - ./scripts:/scripts
    environment:
      - MONGOS=mongo-router
      - MONGO11=mongo-1-1
      - MONGO12=mongo-1-2
      - MONGO13=mongo-1-3
      - MONGO21=mongo-2-1
      - MONGO22=mongo-2-2
      - MONGO23=mongo-2-3
      - RS1=rs1
      - RS2=rs2
      - PORT=27017
      - PORT1=27017
      - PORT2=27017
      - PORT3=27017
    entrypoint: [ "/scripts/init-shard.sh" ]
    restart: on-failure:20
    networks:
      - mongo

networks:
  mongo:
    driver: bridge
    ipam:
      config:
        - subnet: 10.200.1.10/24

部署

#docker-compose.yml当前目录下一键运行docker-compose,也可以使用-f docker-compose.yml指定文件
docker-compose up -d
#查看运行日志,至此分片集群启动和配置完成
docker-compose logs
#查看进程信息或者docker ps
docker-compose ps
##进入路由节点
docker exec -it 1eb3991a6f68 /bin/bash
## 执行mongo客户端
mongo
#查看集群分片信息,目前数据节点由rs1和rs2两个副本集组成
db.stats()
#进入一个副本集节点里
docker exec -it 210f0e977622 /bin/bash
## 执行mongo客户端
mongo
#查看当前所在副本集的集群节点信息
rs.status()

实战

基础命令

MongoDB基于文档的管理,官方提供详细说明,包括插入数据、修改数据、删除数据、基础查询。

spring-boot整合

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>

yaml文件配置

spring:
  data:
    mongodb:
      uri: mongodb://192.168.50.95:30001/test
import cn.aotain.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.*;

@SpringBootTest
class GitTestApplicationTests {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Test
    //批量插入
    void batInsertUser() {
        List<User> users = new ArrayList<>();
        for (long i = 1; i <= 1000; i++) {
            users.add(new User(i,"user"+i, new Random().nextInt(100), UUID.randomUUID().toString(),new Date()));
        }
        mongoTemplate.insert(users,"user_info");
    }        

    @Test
    //查询全部
    public void findAllUser() throws Exception {
        List<User> users = mongoTemplate.findAll(User.class,"user_info");
        System.out.println("查询结果:" + users.toString());
    }

    @Test
    //查询条件
    public void findUserByConditionAndSort() {
        Query query = new Query(Criteria.where("age").is(62)).with(Sort.by("createTime"));
        List<User> users = mongoTemplate.find(query, User.class,"user_info");
        users.forEach(System.out::println);
    }

    @Test
    //查询一个
    public void findOneUser(){
        Query query = new Query(Criteria.where("userId").is(233L));
        User user = mongoTemplate.findOne(query, User.class,"user_info");
        System.out.printf(user.toString());
    }
}

分片键类型

对MongoDB集合进行分片时需要选择一个片键 , 片键是每条记录都必须包含的字段,且为建立了索引的单个字段或复合字段,MongoDB数据库按照片键将数据划分到不同的数据块中,并将数据块均衡地分布到所有分片中。为了按照片键划分数据块,MongoDB使用基于范围的分片方式或者基于哈希的分片方式。但需要注意的是一旦集合设置分片并插入文档之后每个文档的分片的键和值都是不可更改的。如果需要修改文档的分片键,必须要先删除文档,再修改分片键,然后重新插入文档。分片键也不支持数组索引,文本索引和地理空间索引。

  • 基于范围的分片键定义:基于范围的分片键是根据分片键值把数据分成一个个邻接的范围,如果没有指定特定的分片类型,则基于范围的分片键是默认的分片类型。特点:基于范围的分片键对于范围类型的查询比较高效,给定一个片键的范围,分发路由可以很简单地确定哪个数据块存储了请求需要的数据,并将请求转发到相应的分片中。使用场景:建议在分片键基数较大,频率较低,并且分片键值不是单调变化的情况下使用基于范围的分片键。
  • 基于哈希的分片键定义:基于哈希的分片键是指MongoDB数据库计算一个字段的哈希值,并用这个哈希值来创建数据块。特点:保证了集群中数据的均衡。哈希值的随机性使数据随机分布在每个数据块中,因此也随机分布在不同分片中。使用场景:如果分片键值的基数较大,拥有大量不一样的值,或者分片键值是单调变化的,则建议使用基于哈希的分片键。

分片配置

  • 基于范围的分片键设置
#基于范围的分片键设置,使用如下命令,开启数据库分片开关,参数database表示要开启分片集合的数据库
sh.enableSharding(database)
#设置分片键,参数namespace表示需要进行分片的目标集合的完整命名空间<database>.<collections>,key表示要设置分片键的索引,如果需要进行分片的目标集合是空集合,可以不创建索引直接进行下一步的分片设置,该操作会自动创建索引,如果需要进行分片的目标集合是非空集合,则需要先创建索引key。然后使用如下命令设置分片键。
sh.shardCollection(namespace, key)
  • 哈希的分片键设置
然后再使用如下命令创建基于哈希的分片键#基于范围的分片键设置,使用如下命令,开启数据库分片开关,参数database表示要开启分片集合的数据库
sh.enableSharding(database)
#设置基于哈希的分片键,其中numInitialChunks值的估算方法是:db.collection.stats().size / 10*1024*1024*1024。
sh.shardCollection("<database>.<collection>", { <shard key> : "hashed" }* , false, {numInitialChunks: 预置的chunk个数})
#如果集合已经包含数据,则需要先使用如下命令对需要创建的基于哈希的分片键先创建哈希索引
db.collection.createIndex()
#然后再使用如下命令创建基于哈希的分片键
sh.shardCollection()

分片实验

#基于Hash分片
sh.enableSharding("test")
sh.shardCollection("test.user_info_shard",{ "userId" : "hashed" },false)

我们往test.user_info_shard集合中插入10000条数据,查看两个rs中的文档数可以看到数据已经分散到两个副本集集群中了。

相关推荐

辞旧迎新,新手使用Containerd时的几点须知

相信大家在2020年岁末都被Kubernetes即将抛弃Docker的消息刷屏了。事实上作为接替Docker运行时的Containerd在早在Kubernetes1.7时就能直接与Kubelet集成使...

分布式日志系统ELK+skywalking分布式链路完整搭建流程

开头在分布式系统中,日志跟踪是一件很令程序员头疼的问题,在遇到生产问题时,如果是多节点需要打开多节点服务器去跟踪问题,如果下游也是多节点且调用多个服务,那就更麻烦,再者,如果没有分布式链路,在生产日志...

Linux用户和用户组管理

1、用户账户概述-AAA介绍AAA指的是Authentication、Authorization、Accounting,即认证、授权和审计。?认证:验证用户是否可以获得权限,是3A的第一步,即验证身份...

linux查看最后N条日志

其实很简单,只需要用到tail这个命令tail-100catalina.out输入以上命令,就能列出catalina.out的最后100行。...

解决linux系统日志时间错误的问题

今天发现一台虚拟机下的系统日志:/var/log/messages,文件时间戳不对,跟正常时间差了12个小时。按网上说的执行了servicersyslogrestart重启syslog服务,还是不...

全程软件测试(六十二):软件测试工作如何运用Linux—读书笔记

从事过软件测试的小伙们就会明白会使用Linux是多么重要的一件事,工作时需要用到,面试时会被问到,简历中需要写到。对于软件测试人员来说,不需要你多么熟练使用Linux所有命令,也不需要你对Linux...

Linux运维之为Nginx添加错误日志(error_log)配置

Nginx错误日志信息介绍配置记录Nginx的错误信息是调试Nginx服务的重要手段,属于核心功能模块(nginx_core_module)的参数,该参数名字为error_log,可以放在不同的虚机主...

Linux使用swatchdog实时监控日志文件的变化

1.前言本教程主要讲解在Linux系统中如何使用swatchdog实时监控日志文件的变化。swatchdog(SimpleWATCHDOG)是一个简单的Perl脚本,用于监视类Unix系统(比如...

syslog服务详解

背景:需求来自于一个客户想将服务器的日志转发到自己的日志服务器上,所以希望我们能提供这个转发的功能,同时还要满足syslog协议。1什么是syslog服务1.1syslog标准协议如下图这里的fa...

linux日志文件的管理、备份及日志服务器的搭建

日志文件存放目录:/var/log[root@xinglog]#cd/var/log[root@xinglog]#lsmessages:系统日志secure:登录日志———————————...

运维之日志管理简介

日志简介在运维过程中,日志是必不可少的东西,通过日志可以快速发现问题所在。日志分类日志分类,对不同的日志进行不同维度的分析。操作系统日志操作系统是基础,应用都是在其之上;操作系统日志的分析,可以反馈出...

Apache Log4j 爆核弹级漏洞,Spring Boot 默认日志框架就能完美躲过

这两天沸沸扬扬的Log4j2漏洞门事件炒得热火朝天:突发!ApacheLog4j2报核弹级漏洞。。赶紧修复!!|Java技术栈|Java|SpringBoot|Spring...

Linux服务器存在大量log日志,如何快速定位错误?

来源:blog.csdn.net/nan1996jiang/articlep/details/109550303针对大量log日志快速定位错误地方tail/head简单命令使用:附加针对大量log日志...

Linux中查看日志文件的正确姿势,求你别tail走天下了!

作为一个后端开发工程师,在Linux中查看查看文件内容是基本操作了。尤其是通常要分析日志文件排查问题,那么我们应该如何正确打开日志文件呢?对于我这种小菜鸡来说,第一反应就是cat,tail,vi(或...

分享几款常用的付费日志系统,献给迷茫的你!

概述在前一篇文章中,我们分享了几款免费的日志服务器。他们各有各的特点,但是大家有不同的需求,有时免费的服务器不能满足大家的需要,下面推荐几款付费的日志服务器。1.Nagios日志服务器Nagio...

取消回复欢迎 发表评论: