精华内容
下载资源
问答
  • 分片

    千次阅读 2017-11-26 21:19:36
    MyCat分片-海量数据存储解决方案1 什么是分片简单来说,就是指通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)上面,以达到分散单台设备负载的效果。 数据的切分(Sharding)...

    MyCat分片-海量数据存储解决方案

    1 什么是分片

    简单来说,就是指通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)上面,以达到分散单台设备负载的效果。
    数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式。

    (1)一种是按照不同的表(或者Schema)来切分到不同的数据库(主机)之上,这种切分可以称之为数据的垂直(纵向)切分

    (2)另外一种则是根据表中的数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面,这种切分称之为数据的水平(横向)切分。

    MyCat分片策略:

    2 分片相关的概念

    逻辑库(schema) :

    通常对实际应用来说,并不需要知道中间件的存在,业务开发人员只需要知道数据库的概念,所以数据库中间件可以被看做是一个或多个数据库集群构成的逻辑库。

    • 逻辑表(table):

    既然有逻辑库,那么就会有逻辑表,分布式数据库中,对应用来说,读写数据的表就是逻辑表。逻辑表,可以是数据切分后,分布在一个或多个分片库中,也可以不做数据切分,不分片,只有一个表构成。

    • 分片表:

    是指那些原有的很大数据的表,需要切分到多个数据库的表,这样,每个分片都有一部分数据,所有分片构成了完整的数据。 总而言之就是需要进行分片的表。

    • 非分片表:

    一个数据库中并不是所有的表都很大,某些表是可以不用进行切分的,非分片是相对分片表来说的,就是那些不需要进行数据切分的表。

    • 分片节点(dataNode)

    数据切分后,一个大表被分到不同的分片数据库上面,每个表分片所在的数据库就是分片节点(dataNode)。

    • 节点主机(dataHost)

    数据切分后,每个分片节点(dataNode)不一定都会独占一台机器,同一机器上面可以有多个分片数据库,这样一个或多个分片节点(dataNode)所在的机器就是节点主机(dataHost),为了规避单节点主机并发数限制,尽量将读写压力高的分片节点(dataNode)均衡的放在不同的节点主机(dataHost)。

    • 分片规则(rule)

    前面讲了数据切分,一个大表被分成若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将极大的避免后续数据处理的难度。

    3 MyCat分片配置

    (1)配置schema.xml

    schema.xml作为MyCat中重要的配置文件之一,管理着MyCat的逻辑库、逻辑表以及对应的分片规则、DataNode以及DataSource。弄懂这些配置,是正确使用MyCat的前提。这里就一层层对该文件进行解析。

    schema 标签用于定义MyCat实例中的逻辑库

    Table 标签定义了MyCat中的逻辑表
    rule用于指定分片规则,auto-sharding-long的分片规则是按ID值的范围进行分片 1-5000000 为第1片
    5000001-10000000 为第2片….

    dataNode 标签定义了MyCat中的数据节点,也就是我们通常说所的数据分片。

    dataHost标签在mycat逻辑库中也是作为最底层的标签存在,直接定义了具体的数据库实例、读写分离配置和心跳语句。

    在服务器上创建3个数据库,分别是db1 db2 db3

    修改schema.xml如下:

    <?xml version="1.0"?>
    <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
    <mycat:schema xmlns:mycat="http://org.opencloudb/">
    <schema name="MYSCHEMA" checkSQLschema="false" sqlMaxLimit="100">
        <table name="tb_test" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
    </schema>
    <dataNode name="dn1" dataHost="localhost1" database="db1" />
    <dataNode name="dn2" dataHost="localhost1" database="db2" />
    <dataNode name="dn3" dataHost="localhost1" database="db3" />
    <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
        writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <writeHost host="hostM1" url="192.168.25.142:3306" user="root"
            password="123456">
        </writeHost>
    </dataHost> 
    </mycat:schema>
    

    (2)配置 server.xml

    server.xml几乎保存了所有mycat需要的系统配置信息。最常用的是在此配置用户名、密码及权限。在system中添加UTF-8字符集设置,否则存储中文会出现问号

    <property name="charset">utf8</property>
    

    修改user的设置 , 我们这里为 数据库设置了两个用户

    <user name="test">
        <property name="password">test</property>
        <property name="schemas">MYSCHEMA</property>
    </user>
    <user name="root">
        <property name="password">123456</property>
        <property name="schemas">MYSCHEMAB</property>
    </user>
    

    4 MyCat分片测试

    进入mycat ,执行下列语句创建一个表:

    CREATE TABLE tb_test (
      id BIGINT(20) NOT NULL,
      title VARCHAR(100) NOT NULL ,
      PRIMARY KEY (id)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8 
    

    创建后你会发现,MyCat会自动将你的表转换为大写,这一点与Oracle有些类似。

    我们再查看MySQL的3个库,发现表都自动创建好啦。好神奇。

    接下来是插入表数据,注意,在写INSERT语句时一定要写把字段列表写出来,否则会出现下列错误提示:
    错误代码: 1064
    partition table, insert must provide ColumnList
    我们试着插入一些数据:

    INSERT INTO TB_TEST(ID,TITLE) VALUES(1,'goods1');
    INSERT INTO TB_TEST(ID,TITLE) VALUES(2,'goods2');
    INSERT INTO TB_TEST(ID,TITLE) VALUES(3,'goods3');
    

    我们会发现这些数据被写入到第一个节点中了,那什么时候数据会写到第二个节点中呢?

    我们插入下面的数据就可以插入第二个节点了

    INSERT INTO TB_TEST(ID,TITLE) VALUES(5000001,'goods5000001');
    

    因为我们采用的分片规则是每节点存储500万条数据,所以当ID大于5000000则会存储到第二个节点上。

    目前只设置了两个节点,如果数据大于1000万条,会怎么样呢?执行下列语句测试一下

    INSERT INTO TB_TEST(ID,TITLE) VALUES(10000001,'goods10000001');
    

    5 MyCat分片规则

    rule.xml用于定义分片规则 ,我们这里讲解两种最常见的分片规则

    (1)按主键范围分片rang-long

    在配置文件中我们找到

    <tableRule name="auto-sharding-long">
        <rule>
            <columns>id</columns>
            <algorithm>rang-long</algorithm>
        </rule>
    </tableRule>
    

    tableRule 是定义具体某个表或某一类表的分片规则名称 columns用于定义分片的列 algorithm代表算法名称 我们接着找rang-long的定义

    <function name="rang-long"
        class="org.opencloudb.route.function.AutoPartitionByLong">
        <property name="mapFile">autopartition-long.txt</property>
    </function>
    

    Function用于定义算法 mapFile 用于定义算法需要的数据,我们打开autopartition-long.txt

    # range start-end ,data node index
    # K=1000,M=10000.
    0-500M=0
    500M-1000M=1
    1000M-1500M=2
    

    (2)一致性哈希murmur
    当我们需要将数据平均分在几个分区中,需要使用一致性hash规则
    我们找到function的name为murmur 的定义,将count属性改为3,因为我要将数据分成3片

    <function name="murmur"
        class="org.opencloudb.route.function.PartitionByMurmurHash">
        <property name="seed">0</property><!-- 默认是0 -->
        <property name="count">3</property><!-- 要分片的数据库节点数量,必须指定,否则没法分片 -->
        <property name="virtualBucketTimes">160</property><!-- 一个实际的数据库节点被映射为这么多虚拟节点,默认是160倍,也就是虚拟节点数是物理节点数的160倍 -->
        <!-- <property name="weightMapFile">weightMapFile</property> 节点的权重,没有指定权重的节点默认是1。以properties文件的格式填写,以从0开始到count-1的整数值也就是节点索引为key,以节点权重值为值。所有权重值必须是正整数,否则以1代替 -->
        <!-- <property name="bucketMapPath">/etc/mycat/bucketMapPath</property> 
            用于测试时观察各物理节点与虚拟节点的分布情况,如果指定了这个属性,会把虚拟节点的murmur hash值与物理节点的映射按行输出到这个文件,没有默认值,如果不指定,就不会输出任何东西 -->
    </function>
    

    我们再配置文件中可以找到表规则定义

    <tableRule name="sharding-by-murmur">
        <rule>
            <columns>id</columns>
            <algorithm>murmur</algorithm>
        </rule>
    </tableRule>
    

    但是这个规则指定的列是id ,如果我们的表主键不是id ,而是order_id ,那么我们应该重新定义一个tableRule:

    <tableRule name="sharding-by-murmur-order">
        <rule>
            <columns>order_id</columns>
            <algorithm>murmur</algorithm>
        </rule>
    </tableRule>
    

    在schema.xml中配置逻辑表时,指定规则为sharding-by-murmur-order

    <table name="tb_order" dataNode="dn1,dn2,dn3" rule="sharding-by-murmur-order" />
    

    最后可插入一些数据查看分片效果

    展开全文
  • 服务层分片——RDB 分片新思路

    万次阅读 2019-04-19 09:46:14
    目前国内流行的开源数据库分片实现都基于 SQL 的改写、分发与结果归并。但这种实现存在一些无法避免的缺陷,本文试图说明白这些缺陷的由来及提供一个传统数据库分片实现的新思路。 流行分片框架实现分析 目前国内...

    目前国内流行的开源数据库分片实现都基于 SQL 的改写、分发与结果归并。但这种实现存在一些无法避免的缺陷,本文试图说明白这些缺陷的由来及提供一个传统数据库分片实现的新思路。

    流行分片框架实现分析

    目前国内流行的开源 RDB(Relation Database) 分片框架,无论是在 应用端 进行分片还是利用 中间件 进行分片, 其都基于 SQL 进行,主要的流程是:

    1. 解析上层传入的 SQL
    2. 结合对应的分表分库配置,对传入的 SQL 进行改写并分发到对应的单机数据库上
    3. 获得各个单机数据库的返回结果后,根据原 SQL 归并结果,返回用户原 SQL 期待的结果

    这种实现希望从 SQL 层提供一个屏蔽底层分片逻辑的解决方案,对上层应用来说,只有一个 RDB,这样应用可以 透明地访问多个数据库

    然而,这仅仅只是一个美丽的目标。因种种原因,目前流行的开源 SQL 层分片方案无法提供跟原生数据库一样的功能:

    • ACID 里的 A(原子性)无法保证
    • ACID 里的 C(一致性)可能被打破
    • ACID 里的 I(隔离性)与原生不一致
    • 由于 SQL 解析复杂,性能等考虑,很多数据库 SQL 不支持

    除了上面与原生数据库的差异外,读写分离在基于 SQL 的框架也无法完美实现。

    以下我们浅析一下这类基于 SQL 的分片框架不能达到上面要求的原因。

    一些经过大量魔改的商业数据库中间件能实现与单机数据库一致的 AC 特性,I 特性也能达到 RR(Reapeatable Read)级别,但其实现较为复杂,大量处理逻辑都迁移到了中间件中,也不开源,本文暂不讨论。

    原子性

    分片框架如果要保证跨分片的原子性,有两个选择。

    2PC(Two-phase Commit)

    其利用 WriteAheadLog 及锁之类的阻塞等待机制确保分布式事务的强一致性。

    最终一致

    其不要求多个分布式系统对于某个跨库事务马上达到一致的状态,只要最终某   个时间点达到一致即可。

    若使用 2PC,就像大家都听说的,因其需要同步协调处理数据,维护使用的锁,性能会降低(据说 20% 左右)。

    若存在分片节点宕机的情况,会导致与这个分片相关的事务都变慢(其他分片等待这个宕机分片的反馈,超时才回滚),甚至引起雪崩效应,导致整个集群不可用。

    同时 2PC 实现复杂度也较高,据我了解目前开源的实现中没有提供 2PC 的事务支持。

    最终一致可以实现跨分片大事务的最终的原子性。只要发起方分片能正常运作,那么客户操作就能进行。然而,在 SQL 层实现最终一致是不合适的。

    首先,能否使用最终一致是由 业务决定 的,其跟业务设计强耦合;其次基于 SQL 层做最终一致时要求跨分片的 SQL 必须可重复执行(幂等),如

    update account set account.money=1000;

    而不能是

    update account set account.money 
    = account.money + 1000;

    同时若未达到最终一致的情况下,读取了记录,并依赖于此进行了判断及记录修改的话,则会产生错误的数据。单机数据库 ACID 的意义荡然无存。

    我们至少可以推断出,这类在 SQL 层做的最终一致性 越位 了,在 SQL 层无法优雅的实现最终一致,最终一致是服务层(业务层次)的事情。

    因此开源分片框架基本都不保证 A。为了实现跨库的 Update 操作,基于 SQL 的分片框架们创造了一个概念“弱 XA”。其主要实现流程如下:

    • 执行 A 分片的 SQL

    • 执行 B 分片的 SQL

    • 执行 A 库的提交

    • 执行 B 库的提交

    其可以做到:整体事务 COMMIT 前,若有任何异常,都可完美回滚。

    但其存在的缺陷是:当 A 库提交后,B 库失败的话,整个事务就会处于不一致的状态。

    当然,交易量少的时候,这个出错的概率就比较少。但交易量变多的话,这里总会因为网络抖动等各种原因产生错误。

    一致性

    其实一致性是跟原子性有所关联的,只要原子性没能保证,那么一致性肯定是无法保证的。

    隔离级别

    隔离级别在 SQL92 里定义的是这么四个:脏读、读已提交、可重复读、可序列化。

    它们并非无关痛痒的几个数据库参数。隔离级别不一样,对应的在我们的程序里要实现业务一致性的代码逻辑也不一样。

    然而基于 SQL 的分片框架在跨分片访问时提供的事务隔离级别并非原生数据库里定义的,而是一个新的,未被广泛理解认可的事务隔离级别。

    程序员如果没能领悟这个区别,程序执行过程中很有可能就会出现程序员自己也无法理解的错误。

    SQL 兼容性

    由于 SQL 解析的复杂性及性能等因素,基于 SQL 的分片框架有很多 SQL 的解析是不支持的。并且由于 SQL 解析确实很复杂,对于其声明的支持的 SQL 存在 BUG 的可能性也很大。

    至于具体哪些 SQL 不支持,本文就不再分析,大家可以阅读相关框架文档得知。

    读写分离

    读写分离并非原生数据库里支持的功能,但一个较好的读写分离实现应该是能在读库里跑读事务的。

    然而很多人,认为进行只读操作时,加事务是没意义的。如果有这么认识的人,我觉得可能并没有透彻理解 ACID 中的 I。

    举一个例子,一个界面上,需要展示客户的余额以及他的转账记录。如果余额跟转账记录的查询不在一个 RR 级别的事务里进行的话,那么查询出来的结果就有可能出现余额跟转账记录对不上的情况!

    如果是客户 UI 查询还好,刷新一下就好了。但如果是为了生成对账文件,那不就出现大问题了?

    然而,在基于 SQL 层的分片实现中,是没有办法做到完美的读写分离的。因其无法知道这个事务究竟是读事务,还是写事务,因此在第一条 SQL 执行时无法确定要走读库还是写库。

    因此,在基于 SQL 层的分片框架中的做法基本都是:

    • 若有事务,直接走写库

    • 若无事务,直接走读库,若后续发生了 Update 操作,则线程后续操作都走写库

    由此可见,这种读写分离,是不完善的,要实现 RR 级别的读,只能走主库,或者只能返回一个隔离级别混乱的数据集。

    分片新思路――服务层分片

    正因为基于 SQL 的分片框架提供的 ACID 特性与原生的不一样,所以,在上层应用 SQL 编码过程中,必须明确经过分片框架封装后的 ACID 特性是怎样的,并根据该框架的特性,写出对应调整后的 SQL 才能得到正确可靠的代码逻辑。分片框架的特性一直影响着 SQL 的实际形式。

    因此,基于 SQL 的分片方案对应用层并不透明。

    如果要基于 SQL 层的框架写出正确可靠的代码的话,大多数情况下需要遵循的一条原则是:所有事务(包括读、写)都不能跨库。(某些对隔离级别要求不是很高的业务可以允许读跨库)

    如果要遵循上面的指导原则的话,那么,实际上,大多数情况下,我们需要的分片框架提供的仅仅只是选择一个合适的数据源而已。

    结合之前关于读写分离的分析,如果分片实现改在 Service 层,可以清晰地看到会有以下两点好处:

    • Service 层有明确的读 / 写事务信息,能实现理想的 RR 级别读写分离

    • Service 层的入参里就有供选择分片的信息,无需经过复杂的 SQL 解析就可以选定分片,完成我们对分片框架的绝大多数需求

    基于以上两点好处,本人尝试编写了一个基于 Service 层的分片框架,以下展示本人在 Service 层实现分片的一个框架的使用方法,后续我们将更详细地分析该实现的优缺点。

    基本使用方法

    Service 层

    @Service
    @ShardingContext(dataSourceSet="orderSet",
    shardingKeyEls="[user].userId",
    shardingStrategy="@modUserId",
    generateIdStrategy="@snowflaker",
    generateIdEls="[user].userId")
    public class UserServceImpl {
    @Autowired
    private UserDaoImpl userDao;
    @Transactional
    @SelectDataSource
    public void updateUser(User user){
    userDao.updateUser(user);
    }
    @Transactional
    @SelectDataSource
    @GenerateId
    public void saveUser(User user){
    userDao.saveUser(user);
    }
    @Transactional(readOnly=true)
    @SelectDataSource(keyNameEls="[userId]")
    public User findUser(int userId){
    return userDao.findUser(userId);
    }
    public List<User> findAllUsers(){
    return userDao.findAllUsers();
    }
        public double calcUserAvgAge(){
        List<User> allUsers = userDao.findAllUsers();
        return allUsers.stream().mapToInt(u->u.getAge())
    .average().getAsDouble();
        }

    @ShardingContext 表示当前的 Service 的分片上下文,就是说,如果有选择数据源、Map 到各数据库 Reduce 出结果、生成 ID 等操作时,如果某些参数没有指定,都从这个 ShardingContext 里面的配置取

    @SelectDataSource 表示为该方法内执行的 SQL 根据分片策略选择一个分片数据源,在方法结束返回前,不能更改分片数据源

    @GenerateId 表示生成 ID,并将其赋值到参数的指定位置

    @GenerateId 对应的逻辑会先执行,然后到 @SelectDataSource 然后到 @Transaction

    @Transactional(readOnly=true) 标签指定了事务是只读的,因此框架会根据 readOnly标志自动选择读库(如果有的话)

    从方法 calcUserAvgAge 可以看到在 JDK8 的 LAMBADA 表达式及 Stream 功能下,JAVA 分析处理集合数据变得极为简单,复杂度基本与 SQL 语句一致,这会大大减少我们自行加工分片数据的复杂度。

    DAO 层

    @Component
    public class UserDaoImpl {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    public void updateUser(User user){
    int update = jdbcTemplate.update
    ("UPDATE `user` SET `name`=? WHERE 
    `user_id`=?;",user.getName(),user.getUserId());
    Assert.isTrue(update == 1,"it should be updated!");
    }
    public User findUser(int userId){
    return jdbcTemplate.queryForObject
    ("SELECT * FROM user WHERE user_id = ?", 
    new Object[]{userId}, rowMapper);
    }
    @Transactional
    @MapReduce
    public List<User> findAllUsers(){
    return jdbcTemplate.query
    ("SELECT * FROM user", rowMapper);
    }
    @Transactional(readOnly=true)
    @MapReduce
    public void findAllUsers
    (ReduceResultHolder resultHolder){
       List<User> shardingUsers = jdbcTemplate.query
    ("SELECT * FROM user", rowMapper);
       resultHolder.setShardingResult(shardingUsers);
    }
    }

    @MapReduce 表示该方法将会在每个数据分片都执行一遍,然后进行数据聚合后返回。

    对于聚合前后返回的数据类型一致的方法,调用时可以直接从返回值取得聚合结果。

    对于聚合前后返回的数据类型不一致的方法,需要传入一个对象 ReduceResultHolder,调用完成后,通过该对象获得聚合结果。

    默认情况下,框架会提供一个通用 Reduce 策略,如果是数字则累加返回,如果是Collection 及其子类则合并后返回,如果是 MAP 则也是合并后返回。

    如果该策略不适合,那么用户可自行设计指定 Reduce 策略。

    @Transaction 表示每一个分片执行的 SQL 都处于一个事务中,并不是表示整个聚合操作是一个整体的事务。所以,MapReduce 最好不要进行更新操作(考虑框架层次限制 MapReduce 只允许 ReadOnly 事务,目前仍没有做限制)。

    @MapReduce 执行的操作会在 @Transaction 之前。

    优缺点分析

    针对上述实现,我们可以分析一下如此实现的优缺点。

    优点

    • 框架实现简单,无 SQL 解析改写等复杂逻辑,BUG 理论上更少,也容易排查 BUG

      个人认为这至为重要,至少这个简单的框架在使用者的可控范围内。

    • 全数据库、全 SQL 兼容

      SQL 层分片无法做到。

    • 能完美实现读写分离

      Service 层分片在 Service 开始前就能确定该事务是读事务,整个读事务都在一个读库中完成,隔离级别与数据库一致,能实现完美 RR 级别读写分离。

    • 使用注解完成分片,无业务逻辑入侵

      如果注解也算的入侵的话,那么 Spring 就彻底浸入了我们的业务代码里了。

      使用注解能显式的提醒程序员及 REVIEWER,这是在访问单库还是跨库访问,而不像基于 SQL 的分片,隐式完成了跨库这一不安全的操作。

    • 隔离级别及事务原子性等特征与使用的数据库一致,无额外学习负担,易于写出正确的程序

      框架限制了所有事务都在单库进行。

    • 无额外维护 DBProxy 可用性的负担

    • 无 SQL 解析成本,性能更高

    缺点

    • 跨库查询需要自行进行结果聚合

      • 是劣势也是优势

      • 劣势:需要完成额外的聚合代码

      • 优势:显式提示程序员这是聚合操作,且其能能更好地调优, 使用 JDK8 的 Stream 及 Lambada 表达式,能像写 SQL 一样简单地完成相关集合处理。同时合理设计的代码里,聚合操作应该只存在于少量的非核心操作中,因此不会增加太多的工作量。聚合计算出结果这部分内容实际上是可以上升成 Service 层的逻辑的(若不考虑严格的领域设计模型那一套的话)。

    • 跨库事务需要自行保证

      • 是劣势也是优势

      • 劣势:需要额外自行实现跨库事务

      • 优势:目前所有的开源分片框架实现的跨库事务都有缺陷或者说限制。因此自行采用显式的事务控制,结合业务实现最终一致性或许是更好的选择。可参考使用本人写的另外一个框架 EasyTransaction。

    • 无法实现单库分表

    • 其实,单库分表并不是必须的,这可以用数据原生的表分区来实现,性能一样,使用更便捷

    • 如果你拒绝使用数据库原生的表分区,而使用改写表名的形式做库内分片时,你最好能清楚意义在哪里,而不是想当然。

    结语

    实际上,我对基于 SQL 进行分片的框架并非拒绝,我也衷心佩服对这些开源框架做出贡献的大神们,此文仅仅给大家一些新的分片思路。若本文能给大家一些小小的启发,那么希望大家能帮忙给我的两个项目加加星,感谢。

    服务层分片框架

    分布式柔性事务框架

    展开全文
  • IP分片

    万次阅读 2020-09-14 23:01:16
    为了使超过此上限的ip数据报能够正常传输,IP引入了“分片”和“重组”。 当IP层接收到要发送的IP数据报时,通过查找“转发表”,会判断该数据报应该从那个本地“接口”发送以及MTU是多少。 不同的网络类型,其...

           链路层通常对可传输的每一个帧的最大长度都有上限。为了使超过此上限的ip数据报能够正常传输,IP引入了“分片”和“重组”。

           当IP层接收到要发送的IP数据报时,通过查找“转发表”,会判断该数据报应该从那个本地“接口”发送以及MTU是多少。

           不同的网络类型,其MTU都不相同,如以太网中MTU为1518字节,FDDI为4500字节。

           如果IP数据报超过MTU值,则进行分片。IPv4的分片可以在原始发送方主机和端到端路径上的任何中间路由器上进行,即:一个分片在到达接收主机的路径中,还可能被继续分片。

     

          当一个IP数据报被分片后,直到它到达最终目的地才会被重组

    展开全文
  • 首先我们要移除的分片之后再次添加此分片时会出现添加失败的情况,需要在添加的分片上登录进行删除此分片之前数据库的历史数据比如testdb,删除分片上的数据库之后就可重新添加此分片到mongos中 1、...

    首先我们要移除的分片之后再次添加此分片时会出现添加失败的情况,需要在添加的分片上登录进行删除此分片之前数据库的历史数据比如testdb,删除分片上的数据库之后就可重新添加此分片到mongos中




    1、执行RemoveShard命令 

    db.runCommand( { removeshard: "your_shard_name" } ) 
    { msg : "draining started successfully" , state: "started" , shard :"mongodb0" , ok : 1 } 
    “注意:该命令至少执行两次才能成功删除,执行到state为completed才真正删除,否则就是没用删除成功,该分片处于"draining" : true状态,该状态下不但该分片没用删除成功,而且还影响接下来删除其他分片操作,遇到该状态再执行一次removeshard即可,最好就是删除分片时一直重复执行删除命令,直到state为completed; 

    还有一个需要注意的地方就是:被成功删除的分片如果想要再加入集群时,必须将data数据目录清理干净才可以再加入集群,否则即使能加入成功也不会存储数据,集合都不会被创建 

    另外:在删除分片的时有可能整个过程出现无限"draining" : true状态,等多久还是这样,而且分片上面的块一个都没有移动到别的分片,解决办法是:在config的config数据库的shard集合中找到该分片的信息,并将draining字段由True改为False,再继续试着删除操作” 

    上面这句会立即返回,实际在后台执行。 

    2、查看迁移状态 
    我们可以反复执行上面语句,查看执行结果。 
    db.runCommand( { removeshard: "your_shard_name" } ) { msg: "draining ongoing" , state: "ongoing" , remaining: { chunks: 42, dbs : 1 }, ok: 1 } 
    从上面可以看到,正在迁移,还剩下42块没迁移完。 
    当remain为0之后,这一步就结束了。 

    3、移出非Shard数据(如果开始就知道是primary可以直接执行 步骤3和4即可,1和2不需要执行) 
    如果你要删除的Shard分片恰好是primary,那么执行这一步,否则请跳过! 
    db.runCommand( { movePrimary: "数据库名称", to: "分片名称" }) 

    这次就不是立即返回了,需要很久,然后会返回如下: 
    { "primary" : "mongodb1", "ok" : 1 } 

    4、最后的清理 
    上面步骤都完成后,还需要再执行一次RemoveShard,清理残余数据。 
    db.runCommand( { removeshard: "mongodb0" } ) 
    执行成功后,会如下结果: 
    { msg: "remove shard completed succesfully" , stage: "completed", host: "mongodb0", ok : 1 } 

    显示completed后,就可以安心的关闭mongod的进程了。
    展开全文
  • 区块链分片:四种跨分片交易方案

    万次阅读 2019-03-19 16:13:49
    《合约分片执行中的状态问题》一文提到了,跨分片合约的难点在于:一个分片对于共同访问的状态的修改,需要及时地让另一个分片知道,否则就容易出现状态错乱。任何支持合约的分片技术,都必须要解决这个问题。目前...
  • Mongodb分片 1. 分片(sharding)是指将数据拆分,将其分散存放在不同的机器上的过程。有时也用分区(partitioning)来表示这个概念。将数据分散到不同的机器上,不需要功能强大的大型计算机就可以  存储更多的...
  • MyCat分片规则之自定义范围分片

    千次阅读 2019-09-04 21:06:48
    实现方式:范围分片,就是我们自己根据某个字段的数值范围来确定这些数据到底存放在哪一个分片上,不过需要我们提前规划好分片字段某个范围属于哪个分片。切分规则根据文件(autopartition-long.txt)配置的范围来进行...
  • ....分片目前被关注的热度很高,主打分片技术的公链被投资机构热捧, 分片也和Layer 2的侧链、子链、状态通道等方向一起被列入以太坊官方的扩容方案。 1.2分片的原理 分片其实是一种传统数据...
  • mongodb分片

    千次阅读 2020-02-03 14:00:08
    什么是mongodb分片,有什么作用? mongodb分片就是将大型集合分割到不同的服务器上,它可以自动且均衡的分配数据。它一般是针对特别大的需求,比如一个集合需要非常的大,几百个G。分片到10个服务器之后,每个...
  • 干货 | 区块链分片的理念与挑战,Part-1 在连载中的第一部分,我们讨论了为什么要做区块链分片及其他的重要概念。在本文中,我们从更前沿的角度来看分片,包含分片尚未解决的两大挑战:数据有效性和数据可用性。 ...
  • 来源 | Hackernoon译者| 火火酱责编 | Carol出品|区块链大本营(blockchain_camp) 以太坊是所有区块链中一直与分片概念同步的底层平...
  • MySQL的分片(二)——MySQL分片

    万次阅读 2018-10-18 14:25:34
    第一,了解MySQL分片可以更合理地定制分片策略,选分片字段是要讲科学的。 第二,了解MySQL分片以后如果出现故障报错,也有助于问题的排查。 第三,关系到开发过程中的代码调整,做分片后的MySQL数据库操作受到...
  • 一、分片与副本设置 1、分片(shard) Elasticsearch集群允许系统存储的数据量超过单机容量,实现这一目标引入分片策略shard。在一个索引index中,数据(document)被分片处理(sharding)到多个分片上。Elastic...
  • 1 MyCat分片规则 数据切分中重要的几条原则,其中有几条数据冗余,表分组(Table Group)。 1.1全局表 如果你的业务中有些数据类似于数据字典,比如配置文件的配置,常用业务的配置或数据量不是很大,很少变动...
  • 取模分片,简单来讲,根据数据库的主键和存储的节点数进行取模操作,然后根据取模的结果,将数据存放到对应的节点中,取模分表,可以将数据均匀的分配到各个库中。实现的步骤:1、创建数据库,2、配置schema.xml文件...
  • clickhouse 分片

    千次阅读 2019-12-19 21:22:00
    我们知道mysql数据库如果想做分片,需要使用第三方组件,这是因为mysql在设计之初就没有太多考虑分布式等问题。而clickhouse作为新生代性能之王,分片也是必须的功能。基本上从2015年之后的各种数据库也罢,框架也罢...
  • mongoDB何时使用分片及如何分片

    千次阅读 2018-02-23 17:07:22
    暂时只有何时考虑分片,以后补上如何分片的操作。分片(sharding)是指将数据拆分,将其分散存在不同机器上的过程。那么何时才考虑分片呢,出现如下问题时就该考虑使用分片:1). 当数据量达到T级别的时候,我们的磁盘,...
  • IP报文在分片后,遇到MTU还小于分片报文长度的路由器,会继续分片吗? 会怎么处理这种报文?
  • MongoDB-分片片键

    千次阅读 2019-02-24 17:44:34
    MongoDB-分片片键 1.分片  分片是什么?分片就是将数据存储在多个机器上。当数据集超过单台服务器的容量,服务器的内存,磁盘IO都会有问题,即超过单台服务器的性能瓶颈。此时有两种解决方案,垂直扩展和水平...
  • 分片报文

    千次阅读 2016-05-31 20:12:11
    分片模块按照SIP+DIP+ID号+PROTO转发。前中后三片必须ID号一致,协议一致。1.分片首片配置如下:偏移位:0;字节为838;2.中片配置如下:偏移位:100;*8为800;字节为838;3.尾片配置如下:偏移位:200;*8为1600;...
  • 最近在做web网盘的系统,网盘最基本的功能便是文件上传,但是文件上传当遇到大文件的时候,在web端按传统方式上传简直是灾难,所以大文件上传可以采用分片上传的办法。其主要思路是:1.大文件上传时进行分片;2.分片...
  • TCP的分片和IP分片的区别

    千次阅读 2019-04-01 20:46:07
    IP分片与重组 在IP首部中,标识、标志、片偏移这三部分就是与分片的字段。 标识(Identification): 占16位。IP软件在存储器中维持一个计数器,每产生一个数据报,计数器就加1,并将此值赋给标识字段。但这个...
  • MongoDB分片

    2017-01-20 10:55:01
    分片集群 分片键 数据块 分片的优势 分片前的考虑 分片集合与非分片集合 连接分片集群 分片策略 分片集群中的分片键值空间 分片的字符比较排序规则 其它资源分片是一种将数据分散存储到多台机器的方法,...
  • 本文将重点分析ElasticJob的分片机制: ElasticJob分片工作机制: 1、ElasticJob在启动时,首先会启动是否需要重新分片的监听器。 代码见:ListenerManager#startAllListeners {…; shardingListenerManager....
  • 分片和副本分片如何交互

    千次阅读 2018-02-09 17:21:12
    它包含一个叫 blogs 的索引,有两个主分片,每个主分片有两个副本分片。相同分片的副本不会放在同一节点,所以我们的集群看起来像这样。有三个节点和一个索引的集群我们可以发送请求到集群中的任一节点。 每个...
  • StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm(精准分片)和RangeShardingAlgorithm(范围分片)两个分片算法 PreciseShardingAlgorithm是必选的,用于处理=和IN的分片 ...
  • 当我们在使用shard key切分时,默认是Mongos自动分片,自动设定切分规则。但是我们也可以手动指定分片规则。在后面的一篇博客《MongoDB4.0 Sharded Cluster+Replica Set集群搭建》详细介绍了MongoDB集群的搭建方法,...
  • Redis的分片、预分片技术总结

    千次阅读 2016-07-22 15:47:03
    Redis的分片、预分片技术总结
  • mycat 取模分片,ER分片

    千次阅读 2016-07-25 13:02:33
    要求:把订单分片,商家要查询购买在订单,用户要查询自己的订单。 表设计:用户,商家订单,订单明细,买方订单 分片规则: “用户表”---user_id 取模,“商家订单”----seller_user_id 取模 “订单明细”----...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 39,724
精华内容 15,889
关键字:

分片