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

    千次阅读 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" />
    

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

    展开全文
  • MySQL的分片

    万次阅读 2019-06-27 15:11:20
    第一,了解MySQL分片可以更合理地定制分片策略,选分片字段是要讲科学的。 第二,了解MySQL分片以后如果出现故障报错,也有助于问题的排查。 第三,关系到开发过程中的代码调整,做分片后的MySQL数据库操作受到...

    前言
    从开发人员的角度来说,为什么要了解和掌握MySQL分片?

    第一,了解MySQL分片可以更合理地定制分片策略,选分片字段是要讲科学的。

    第二,了解MySQL分片以后如果出现故障报错,也有助于问题的排查。

    第三,关系到开发过程中的代码调整,做分片后的MySQL数据库操作受到限制,比如join之类的操作,跨分片的操作,事务管理等,都是要注意的,可能需要代码的调整。

    分区、分表、分片、分库的概念
    那么首先,我们要理解一下分区、分表、分片、分库的概念。

    分区,局限于单一数据库节点,将一张表分散存储在不同的物理块中。MySQL5以后支持分区,但是不支持二级分区,并且单机MySQL的性能远远不如Oracle,所以分区并不能解决性能问题。

    分表,分表有两种,应用层面的分表和代理层面的分表。

    应用层面的分表,人工把一张逻辑上完整的表分成若干个小表。比如T_PAYMENT表分为T_PAYMENT_0101…T_PAYMENT_1231。对代码不透明。

    代理层面的分表,通过MERGE引擎或者代理中间件把表分成若干的字表,对应用只保留一个“表壳”,对代码透明。(MERGE引擎示意)

     

    分表和分区比较类似,侧重点不同,分区侧重提高读写性能,分表侧重提高并发性能。两者不冲突,可以配合使用。

    分库,单纯的分库就是垂直切分,把不同业务逻辑的表分开存储在在不同的数据库。

    分片,分片就是分库+分表,属于水平切分,将表中数据按照某种规则放到多个库中,既分表又分库,就相当于原先一个库中的一个表,现在放到了好多个表里面,然后这好多个表又分散到了好多个库中。分片和分区也不冲突。

    MySQL分片
    分片键

    数据分片是将一张分布式表按照指定的分片键(Partition Key)和分片模式(Partition Mode)水平拆分成多个数据片,分散在多个数据存储节点中。对于分片的表,要选取一个分片键。一张分布式表只能有一个分片键,分片键是用于划分和定位表的列,不能修改。

    分片模式

    •枚举/列表List

    {1 => Cluster A, 2 => Cluster B}

    •范围Range (仅支持数字或ASCII字符串类型的分片键)

    {[1 - 100] => Cluster A, [101 - 199] => Cluster B}

    •散列Hash (仅支持数字或ASCII字符串类型的分片键)

    {1024n + 1 => Cluster A, 1024n + 2 => Cluster B}

    分片方式类似于分区方式,可以选择枚举,范围Range或者散列哈希。不同的是分片不支持时间range。

    分片策略

    在做分片的时候,选择合适的分片规则非常重要,将极大地避免后续数据的处理难度,有以下几点需要关注:

    1. 能不分就不分,对于1000万以内的表,不建议分片,通过合适的索引,读写分离等方式,可以更好地解决性能问题。

    2. 分片数量不是越多越好,并且尽量均匀分布在多个存储节点上,只在必要的时候进行扩容,增加分片数量。

    3. 分片键不能为空,不能修改,所以要选择表中中最常用且不变的字段。

    4. 分片键选择时尽量做到可以将事务控制在分片范围内,可以避免出现跨分片的操作。

    5. 选择分片规则时,要充分考虑数据的增长模式,数据的访问模式,分片关联 性问题,以及分片扩容问题。

    总体上来说,分片的选择是取决于最频繁的查询 SQL 的条件。找出每个表最频繁的 SQL,分析其查询条件,以及相互的关系,并结合 ER 图,就能比较准确的选择每个表的分片策略。

    MySQL分片要解决的问题
    事务问题

    分布式数据库分散在多个不同的物理主机,网络环境复杂,关注事务,保证数据一致性是一个问题。

    先看单机环境下的事务管理,以Spring为例,利用注解的事务管理:

        @Override
        @Transactional
        public void service(){
            ...
            UserService.updateUserByUserId(userId);
            ...
            OrderService.updateOrderByOrderNo(orderNo);
            ...
    }
    实际上这段代码相当于:

        @Override
        public void service(){
            ...
            UserService.updateUserByUserId(userId);
            ...
            OrderService.updateOrderByOrderNo(orderNo);
            ...
            try{
                commit();
            }catch(Exception e){
                rollback();
            }
    }

     

    如何给多主机发commit并且保证他们最终状态一致就是分布式事务要解决的问题。

    解决这个问题有两种方案。

    第一种由应用程序和数据库共同控制,将一个跨多个数据库的分布式事务分拆成多个仅处于单个数据库上面的小事务,并通过应用程序来总控各个小事务。

        @Override
        public void service(){
            ...
            userService();
            ...
            try{
                orderService();
            }catch(Exception e){
                rollback();
            }
            ...
            }

        
        @Override
        @Transactional
        public void userService() throws RuntimeException{
            ...
            UserService.updateUserByUserId(userId);
            ...
        }

        @Override
        @Transactional
        public void orderService() throws RuntimeException{
            ...
            OrderService.updateOrderByOrderNo(orderNo);
            ...
        }
    }
    这个方法是性能上比较高效,缺点就是需要应用程序在事务控制上做灵活设计。如果使用 了Spring的事务管理,改动起来会面临一定的困难。

    第二种是交由数据库管理,简单有效。比较常见的方案有两阶段提交2PC、补偿事务TCC,MQ事务消息等。下图演示了2PC的过程。

    除了图中提到的三个缺点,两阶段提交的方案影响的整体性能。

    根据CAP原理,分布式数据库无法做到完全的ACID原则,几乎所有分布式解决方案都牺牲了部分一致性或者可用性。比如用最终一致性代替强一致性。

    跨节点Join的问题

    只要是进行切分,跨节点Join的问题是不可避免的。但是良好的设计和切分却可以减少此类情况的发生。解决这一问题的普遍做法是分两次查询实现。在第一次查询的结果集中找出关联数据的id,根据这些id发起第二次请求得到关联数据。

    如果频次较高,可以考虑添加一张关联表,规避掉join操作,空间换时间。

    在交易时直接将记录插入关联表,即可在查询时查询关联表获得想要的结果。

    跨节点的count,order by,group by以及聚合函数问题

    这些是一类问题,因为它们都需要基于全部数据集合进行计算。多数的代理都不会自动处理合并工作。

    解决方案:与解决跨节点join问题的类似,分别在各个节点上得到结果后在应用程序端进行合并。和join不同的是每个结点的查询可以并行执行,因此很多时候它的速度要比单一大表快很多。但如果结果集很大,对应用程序内存的消耗是一个问题。

    值得提醒的是,如果你的应用中包含大量的此类分析及聚合操作,考虑是否你对系统类型判断有误,是OLAP而非OLTP系统。对于OLAP系统不推荐使用MySQL更不推荐使用DRDS分布式数据库存储。

    数据迁移,容量规划,扩容等问题

    在前期如果对系统数据仓库的容量没有正确的预估,会遇到扩容问题。

    利用对2的倍数取余具有向前兼容的特性(如对4取余得1的数对2取余也是1)来分配数据,避免了行级别的数据迁移,但是依然需要进行表级别的迁移,同时对扩容规模和分表数量都有限制。

    举例说明,扩容前有两个集群作为存储节点,现要扩容为四个。

     

    将原先的备机(A1,B1)升级为主机,然后再分别给他们配置备机,即完成了两倍的扩容。根据前面说的向前兼容的特性,分片规则不需要变化,是目前比较常用的扩容方案。

    这部分实际和开发人员关系不大,了解即可。

    ID问题

    一旦数据库被切分到多个物理结点上,我们将不能再依赖数据库自身的主键生成机制。

    一方面,某个分区数据库自生成的ID无法保证在全局上是唯一的;

    另一方面,应用程序在插入数据之前需要先获得ID,以便进行SQL路由。

    比较常见的ID解决方案是应用生成UUID,或者在数据库中维护一个Sequence表。
     

    跨分片的排序分页

    一般来讲,分页时需要按照指定字段进行排序。当排序字段就是分片字段的时候,我们通过分片规则可以比较容易定位到指定的分片,而当排序字段非分片字段的时候,情况就会变得比较复杂了。为了最终结果的准确性,我们需要在不同的分片节点中将数据进行排序并返回,并将不同分片返回的结果集进行汇总和再次排序,最后再返回给用户。如下图所示:

    上面图中所描述的只是最简单的一种情况(取第一页数据),看起来对性能的影响并不大。但是,如果想取出第10页数据,情况又将变得复杂很多,如下图所示:

    有些读者可能并不太理解,为什么不能像获取第一页数据那样简单处理(排序取出前10条再合并、排序)。其实并不难理解,因为各分片节点中的数据可能是随机的,为了排序的准确性,必须把所有分片节点的前N页数据都排序好后做合并,最后再进行整体的排序。很显然,这样的操作是比较消耗资源的,用户越往后翻页,系统性能将会越差。

    那如何解决分库情况下的分页问题呢?有以下几种办法:

    如果是在前台应用提供分页,则限定用户只能看前面n页,这个限制在业务上也是合理的,一般看后面的分页意义不大(如果一定要看,可以要求用户缩小范围重新查询)。

    如果是后台批处理任务要求分批获取数据,则可以加大page size,比如每次获取5000条记录,有效减少分页数(当然离线访问一般走备库,避免冲击主库)。

    分库设计时,一般还有配套大数据平台汇总所有分库的记录,有些分页查询可以考虑走大数据平台。

    分库策略

    比较常见的两种分库策略,按照范围分库或者按照Mod分库,各有侧重点。

    按照范围分库一般在前期数据量较小,在使用过程中用户数据不断增长,在数据库数量少时全库查询消耗小,后期调整数据库数量也比较容易。

    按照Mod分库在初期就要规划好数据库数量,单库查询性能好,如果调整Mod因子会导致数据库迁移,后期增加数据库数量也比较麻烦。

    实际使用中为了处理简单,一般选mod分库,数据库数量选择2的倍数,方便扩容。

    分库数量

    分库数量首先和单库能处理的记录数有关,一般来说,Mysql 单库超过5000万条记录,Oracle单库超过1亿条记录,DB压力就很大(当然处理能力和字段数量/访问模式/记录长度有进一步关系)。

    在满足上述前提下,如果分库数量少,达不到分散存储和减轻DB性能压力的目的;如果分库的数量多,好处是每个库记录少,单库访问性能好,但对于跨多个库的访问,应用程序需要访问多个库,如果是并发模式,要消耗宝贵的线程资源;如果是串行模式,执行时间会急剧增加。

    最后分库数量还直接影响硬件的投入,一般每个分库跑在单独物理机上,多一个库意味多一台设备。所以具体分多少个库,要综合评估,一般初次分库建议分4-8个库。

    路由透明

    分库从某种意义上来说,意味着DB schema改变了,必然影响应用,但这种改变和业务无关,所以要尽量保证分库对应用代码透明,分库逻辑尽量在数据访问层处理。

    历史数据清理

    历史数据的清理是一个比较棘手的问题。

    假设我有一张订单表,联机系统只保存最近五天的订单,之前的要删除掉。

    我们没办法根据日期进行分片,因为日期每天都在变化,按照日期分片意味着分片规则每天都在变化。这和常见的在Oracle定时任务删除分区和新建分区是不一样的。

    假使我们根据设备进行分片,那么常规情况下,同一天的订单会均匀分布在各个分片上。最起码的原则是避免跨分片操作,因为跨分片操作性能极其低而且很多时候你也不知道会发生什么未知的事情。

    所以比较容易想到的方法就是找到每个分片然后再每个分片上进行单独的数据清理操作。

    如果是自研的分布式架构,应该可以通过脚本将清理语句分别路由到各个分片。如果是使用的开源中间件,大部分都会提供分片操作的方法(如果没有,那只能另寻他法了。)。如果是使用的商业服务的分布式数据库,也会提供分片数据清理操作的方法。

    这部分我自己也确实没有其他更好的方案。
     

     

    // 转自: https://blog.csdn.net/rl_leee/article/details/83143335

    展开全文
  • Mongodb分片 1. 分片(sharding)是指将数据拆分,将其分散存放在不同的机器上的过程。有时也用分区(partitioning)来表示这个概念。将数据分散到不同的机器上,不需要功能强大的大型计算机就可以  存储更多的...

    Mongodb分片

    1. 分片(sharding)是指将数据拆分,将其分散存放在不同的机器上的过程。有时也用分区(partitioning)来表示这个概念。将数据分散到不同的机器上,不需要功能强大的大型计算机就可以

        存储更多的数据,处理更大的负载。

    2. MongoDB支持自动分片(autosharding),可以使数据库架构对应用程序不可见,也可以简化系统管理。对应用程序而言,好像始终在使用一个单机的MongoDB服务器一样。另一方面,

        mongoDB自动处理数据在分片上的分布,也更容易添加和删除分片技术。

    3. 复制与分片的区别:复制时让多台服务器都拥有同样的数据副本,每一台服务器都是其他服务器的镜像,而每一个分片都和其他分片拥有不同的数据子集。

    4. 路由服务器:为了对应用程序隐藏数据库架构的细节,在分片之前要先执行mongos进行一次路由过程。这个路由服务器维护这一个"内容列表",指明了每个分片包含什么数据内容。应用

        程序只需要连接路由服务器,就可以像使用单机一样进行正常的请求了。

    5. 运行sh.status()可以看到集群的状态:分片摘要信心、数据库摘要信息、集合摘要信息。

    6. 要对一个集合分片,首先你要对这个集合的数据库启用分片,执行如下命令:sh.enableSharding("test")

    7. 片键:片键是集合的一个键,MongoDB根据这个键拆分数据。例如:username 。在启用分片之前,先在希望作为片键的键上创建索引:db.users.ensureIndex({"username":1})

    8. 对集合分片:sh.shardCollection("test.users",{"username":1})

    9. 集合被拆分为多个数据块,每个数据块都是集合的一个数据子集。这是按照片键的范围排列的({"username":minValue}-->>{"username":maxValue}指出了每个数据块的范围)。

    10. 包含片键的查询能够直接被发送到目标分片或者是集群分片的一个子集。这样的查询叫做定向查询(targetd query)。有些查询必须被发送到所有分片,这样的查询叫做分散-聚合查询(

          scatter-gather query);mongos将查询分散到所有的分片上,然后经各个分片的查询结果聚集起来。

    11. cluster.stop() 关闭整个集群。

     

    BSON类型

     

    配置分片:

    1. 何时进行分片:决定何时分片是一个值得权衡的问题。通常不必太早分片,因为分片不仅会增加部署的操作复杂度,还要求做出设计决策,而改决策以后很难再改。另外最好也不要在系统

        运行太久之后再分片,因为在一个过载的系统上不停机进行分配是很困难的。

    2. 分片的目的:增加可用的RAM,增加可用磁盘空间,减轻单台服务器的负载,处理单个mongod无法承受的吞吐量。

    3. 一般情况下至少应该创建3个或者以上的分片。

    4. 启动服务器:

        1). 配置服务器:配置服务器相当于集群的大脑,保存着集群和分片的元数据,即各分片包含哪些数据的信息。因此,应该首先建立配置服务器,鉴于它所包含的的数据极端重要性,必须启用

             其日志功能,并确保其数据保存在非易失性驱动器上。每个配置服务器都应该位于单独的物理机上,最好是分布在不同地址位置的机器上。

             a. 启动配置服务器:mongod --configsvr --dbpath  /var/lib/mongodb -f  /var/lib/config/mognd.conf  。需要启动三台配置服务器,且都是可写的。

                 为什么是3台配置服务器?因为我们需要考虑不时之需。但是,也不需要过多的配置服务器,因为配置服务器上的确认操作比较耗时。另外,如果有服务器宕机了,集群源数据就会变成只读的。

                 --configsvr 选项指定mongod为新配置服务器。该选项并非必选项,因为它所做的不过是将mongod的默认监听端口改为27019,并大默认的数据目录改为/data/configdb而已(可以使用

                 --port 和 --dbpath 选项修改这两项配置)。但建议使用--configsvr选项,因为它比价直白地说明了这些配置服务器的用途。

                 配置服务器的1KB相当于200MB知识数据,它保存的真实数据的分布表。由于配置服务器并不需要太多的资源,因此可以将其部署在运行着其他程序的服务器上。 

        2). mongos进程:三个配置服务器均处于运行状态后,启动一个mongos进程供应用程序连接。mongos进程需要配置服务器的地址,所以必须使用--configdb选项启动mongos:

              mongos --configdb config-1:27019,config-2:27019,config-3:27019 -f /var/lib/mongos.conf

              默认情况下,mongos运行在27017端口。mongos本身不保存数据,它会在启动时从配置服务器加载集群数据。

              可以启动任意数量的mongos进程。通常的设置时每个应用程序服务器使用一个mongos进程(与应用服务器运行在同一台机器上)

              每个mongos进程必须按照列表排序,使用相同的配置服务器列表。

        3). 将副本集转换为分片:有两种可能性:已经有一个副本集,或者从零开始建立集群。下例假设我们已经拥有了一个副本集。如果是从零开始的话,可先初始化一个空的副本集,然后按照本例操作。

             a. 告知mongos副本集名称和副本集成员列表:sh.addShard("spock/server-1:27017,server-2:27017,server-4:27017")  mongos能够自动检测到没有包含在副本集成员表中的成员。

             b. 副本集作为分片添加到集群后,就可以将应用程序设置从连接到副本集改为连接到mongos。

             c. 副本集名称spokc被作为分片名称。如果之后希望移除这个分片或者是向这个分片迁移数据,可以使用spock来标志这个分片。

             d. 配置完分片后,必须将客户端设置为将所有请求发送到mongos,而不是副本集。同时配置防火墙规则,以确保客户端不能直接将请求发送到分片。

             e. 有一个--shardsvr选项,与前面介绍的--configsvr选项类似,它也没什么实用性(只是将默认端口改为27018),但在操作中建议使用该选项。

             f. 不建议创建单mongod服务器分片(而不是副本集分片),将单一服务器分片转换为副本集需要停机操作。

        4). 增加集群容量:通过增加分片来增加集群容量。

        5). 数据分片:除非明确指定规则,否则MongoDB不会自动对数据进行拆分。如果有必要,必须明确告知数据库和集合。加入对music数据库中的artists集合按照name进行分片,

              db.enableSharding("music")         对数据库分片是对集合分片的先决条件

              sh.shardCollection("music.artists",{"name":1})   对集合分片,集合会按照name键进行分片。如果是对已存在的集合分片,那么name键上必须有索引,否则会返回错误。

              shardCollection()命令会经集合拆分为多个数据块,这是MongoDB迁移数据的基本单元。命令执行后,MongoDB会均衡的将数据分散到集群的分片上。

    5. MongoDB如何追踪集群数据

        1). MongoDB将文档分组为块(chunk),每个块由给定片键特定范围内的文档组成。一个块只存在于一个分片上,所以MongoDB用一个比较小的表就能够维护跟分片的映射。

        2). 当一个块增长到特定大小时,MongoDB会自动将其拆分为两个较小的块。

        3). 一个常见的误解释同一个块内的数据保存在磁盘的同一片区域。这是不正确的,块并不影响mongod保存集合数据的方式。

        4). 块信息保存在config.chunks集合中。左闭右开。

        5). 可以使用复合片键,工作方式与使用复合索引进行排序一样。

        6). 拆分块:mongos会记录在每个块中插入了多少数据,一旦达到某个阈值,就会检查是否需要对块进行拆分。mongos就会在配置服务器更新这个块的源信息。块拆分中只需要改变块源数据即可,

             而无需进行数据移动。进行拆分时,配置服务器会创建新的块文档,同时修改旧的块范围,拆分完成以后,mongos会重置对原始块的追踪器,同时为新的块创建新的追踪器。

        7). 分片有时可能会找不到任何可用的拆分点,因为合法拆分块方法有限。具有相同片键的文档必须保存在相同的块中。

        8). 如果mongos试图进行拆分时有一个服务器挂了,那么mongos就无法更新源数据。mongos不断重复发起拆分请求却无法进行拆分的过程,叫做拆分风暴。防止拆分风暴的唯一方法是尽可能保证

             配置服务器的可用和健康。也可以重启mongos,重置引入计数器,这样他就不会再处于拆分阈值点了。

        9). 如果mongos进程不断重启,它们的计数器可能永远也不会到达阈值点,因此块的增加不存在最大值,也就无法到达阈值点。

        10). 防止无法拆分的两种方法:一是减少mongos进程的波动,二是使块的大小比实际预期小一些,这样就更容易达到拆分阈值点。

        11). 可以在mongos启动时指定--nosplit选项,从而关闭块的拆分。

    6. 均衡器:均衡器负责数据的迁移。它会周期性地检查分片间是否存在不均衡,如果存在,则会开始块的迁移。虽然均衡器通常被看成单一的实体,但每个mongos有时也会扮演均衡器的角色。

        每隔几秒,mongos就会尝试变身均衡器。如果没有其他可用的均衡器,mongos就会对整个集群加锁,以防止配置服务器对整个集群进行修改,然后做一次均衡。

        mongos成为均衡器后,就会检查每个集合的分块表,从而查看是否有分片达到了均衡阈值。

     

    选择片键

    1. 对集合进行分片时,要选择一或两个字段用于拆分数据,这个键就叫做片键。

    2. 拆分数据最常用的数据分发方式有三种:升序片键、随机分发的片键和基于位置的片键。

        1). 升序片键:升序片键通常有点类似于"date"字段或者是ObjectId,是一种随着时间稳定增长的字段。缺点:例如ObjectId可能会导致接下来的所有的写入操作都在同一块分片上。

        2). 随机分发的片键:随机分发的片键可以是用户名,邮件地址,UDID,MD5散列值或者数据集中其他一些没有规律的键。缺点:MongoDB在随机访问超出RAM大小的数据时效率不高。

        3). 基于位置的片键:基于位置的片键可以是用户的IP、经纬度、或者地址。这里的"位置"比较抽象,不必与实际的物理位置字段相关。

             如果希望特定范围内的块出现在特定的分片中,可以为分片添加tag,然后为块指定相应的tag

    3. 片键策略:

        1). 散列片键:如果追求的是数据加载速度的极致,那么散列片键是最佳选择。散列片键可使其他任何键随机分发,因此,如果打算在大量查询中使用使用升序键,但同时又希望写入数据随机分发的话,

             散列片键会是一个非常好的选择。缺点:无法使用散列片键做指定目标的范围查找。  

             创建步骤: db.users.ensureIndex({"username":"hashed"})   ,   sh.shardCollection("app.users",{"username":"hashed"})

        2). GridFS的散列片键

        3). 流水策略:如果有一些服务器比其他服务器更强大,我们可能希望让这些强大的服务器处理更多的负载。比如说:加入有一个使用SSD的分片能够处理10倍于其他机器的负载。我们可以强制将所有新数据

             插入到SSD,然后让均衡器将旧的块移动到其他分片上。

             a. 为SSD指定一个标签:sh.addShardTag("shard-name","ssd")

             b. 将升序键的当前值一直到正无穷范围的块都指定分布在SSD分片上:sh.addTagRange("dbName.collName",{"_id":ObjectId()},...{"_id":MaxKey},"ssd") 

                 所有插入请求均会路由到这个块上,这个块始终位于标签的ssd的分片上。

             c. 除非修改标签范围,否则从升序键的当前值一直到正无穷都被固定在这个分片上。可以创建一个定时任务每天更新一次标签范围:

                 use config

                 var tag =db.tags.findOne({"ns":"dbName.collName",..."max":{"shardKey":MaxKey}})

                 tag.min.shardKey = ObjectId()

                 db.tags.save(tag)

                 这样前一天的数据就会被移动到其他分片上了。

                 此策略的另一个缺点:需要修改才能进行扩展。如果写请求超出了SSD的处理能力,无法进行负载均衡。

            4). 多热点:写请求分布在集群中时,分片是最高效的。这种技术会创建多个热点(最好在每个分片上都创建几个热点),写请求于是会均衡地分布在集群内,而在单个分片上则是以升序分布的。

                            为了实现这种方式,需使用复合片键。复合片键中的第一个值只是比较粗略的随机值,势也比较低。

    4. 片键规则和指导方针:

        1). 片键限制:片键不可以是数组。文档一旦插入,其片键就无法修改了。要修改文档的片键值,就必须先删除文档。

        2). 片键的势:选择一个值会变化的的键非常重要,即值很多,随着数据量的增大可以分出更多的片键。分片在势比较高的字段上性能更佳。

    5. 控制数据分发

        1). 对多个数据库和集合使用一个集群:通过tag标记,将重要的数据放到性能更好的服务器上,将不重要的数据放在性能一般的服务器上。

        2). 手动分片:如果不希望数据被自动分发,可以关闭均衡器,使用moveChunk命令手动对数据进行迁移。

     

     

    分片管理

    1. 检查集群状态:

        1). 使用sh.status查看集群摘要信息: 块的数量比较多时,sh.status()命令会概述块的状态,而非打印出每个块的相关信息。如需查看所有的块,可使用sh.status(true)命令。

             sh.status()显示的所有信息都来自config数据库。运行sh.status()命令,使用MapReduce获取这一数据。因此,如果启动数据库时指定--noscripting选项,则无法运行sh.status()命令。

        2). 检查配置信息:

             a. 集群相关的所有配置信息都保存在配置服务器上config数据库的集合中。可以直接访问该数据库,不过shell提供了一些辅助函数。

             b. 永远不要直接连接到配置服务器,以防止配置服务器数据被不小心修改或删除。应该先连接到mongos,然后通过config数据库来查询相关信息:use config

                 如果通过mongos操作配置数据,mongos会保证将修改同步到所有配置服务器,也会防止危险的操作发生,如意外删除config数据库等。

             c. 总的来说,不应直接修改config数据库中的任何数据。如果确实修改了某些数据,通常需要重启所有的mongos服务器,才能看到效果。

             d. config中几个关键集合:

                 shards : 跟踪记录集群中所有分片的信息。

                 databases: 跟踪记录集群中所有数据库的信息,不管数据库有没有分片。

                 collections: 跟踪记录所有分片集合的信息(非分片集合信息除外)

                 chunks: 记录集合中所有块的信息。

                 changelog: 跟踪记录集群的操作,因为该集合会记录所有拆分和迁移的操作。

                 tags: 该集合的创建是在为系统配置分片标签时发生的。每个标签都与一个块范围相关联。

                 settings: 该集合含有当前的均衡器设置和块大小的文档信息。通过修改该集合的文档,可开启和关闭均衡器,也可以修改块的大小。注意,应总是连接到mongos修改该集合的值。

    2. 查看网络连接:

        1). 查看连接统计:可以使用connPoolStats命令,查看mongos和mongod之间的连接信息:db.adminCommand({"connPoolStats":1})

                                在一个分片上执行connPoolStats,输出信息中可以看到该分片与其他分片间的连接,包括连接到其他分片做数据迁移的连接。

        2). 限制连接数量: 可在mongos的命令行配置中使用maxConns选项,这样可以限制mongos能够创建的连接数量。可以使用下面公式计算分片能够处理的来自单一mongos连接数量:

                                  maxConns = 20000 - (mongos进程的数量 * 3 ) - (每个副本集的成员数量 * 3 ) - (其他/mongos进程的数量)

                                  MongoDB如果没有安全退出,那些已经打开的套接字很可能没有被关闭。

                                  在出现大量重新连接时,除了重启进程,没有其他特殊有效的方法。

    3. 服务器管理

        1). 添加服务器:使用addShard命令,向集群中添加新的分片

        2). 修改分片的服务器:要修改分片的成员,需直接连接到分片的主服务器上,然后对副本集进行重新配置。集群配置会自动检测更改,并将其更新到config.shards上。

        3). 通常来说,不应从集群中删除分片。执行removeShard命令排除数据和查看排出进度。

        4). 修改配置服务器:修改配置服务器非常困难,而且有风险,通常还需要停机。注意,修改配置服务器前,应做好备份。

                                    首先必须关闭所有mongos进程,然后使用新的--configdb参数重启所有mongos进程。

    4. 数据均衡:

        1). 均衡器:均衡器只使用块的数量,而非数据大小,作为衡量分片间是否均衡的指标。自动均衡总是根据数据集的当前状态来决定数据迁移,而不考虑数据集历史状态。我们可以手动均衡数据集块的数量。

        2). 修改块的大小:块的大小默认为64M,这个大小的块既易于迁移,又不至于导致过多的流失。使用shell连接到mongos,修改config.setting集合,从而完成块大小的修改。

              该设置的有效范围是整个集群:它会影响所有集合的数据库。因此,如需对一个集合使用较小的块,而对另一个集合使用较大的块,比较好的解决方式是取一个折中值(或者将这两个值放到不同的集合中)。

              如果MongoDB频繁进行数据迁移或文档增大,则可能需要增加块的大小。

        3). 迁移块:同一块内的所有数据都位于同一分片上。如该分片的块数量比其他分片多,则MongoDB会将其中的一部分块迁移到其他块数量较少的分片上。移动快的过程叫迁移,MongoDB就是这样在集群中

             实现数据均衡的。可在shell中使用moveChunk辅助函数,手动移动块。

             如果某个块的大小超出了系统指定的最大值,mongos则会拒绝移动这个块。移动之前必须先手动拆分这个块,可以使用splitAt命令对块进行拆分。特大块,无法被拆分。

        4). 特大块:某些片键,值比较少,例如:日期等。可能会形成超出设置的最大块大小的块,这种块成为特大块.

             出现特大块的表现之一是,某个分片的大小增长速度要比其他分片块的多。也可使用sh.status()来检查是否出现了特大块;特大块会存在一个jumbo属性。

             a. 分发特大块,一个复杂的过程

             b. 防止特大块的出现:修改片键,细化片键的粒度

        5). mongos有时无法从配置服务器正确更新配置。如果发现配置有误,mongos的配置过旧或无法找到应有的数据,可以使用flushRouterConfig命令手动刷新所有缓存:db.adminCommand({"flushRouterConfig":1})

             如flushRouterConfig命令没能解决问题,则应重启所有的mongos或者mongod进程,以便清除所有可能的缓存。

    展开全文
  • 跟我学ShardingSphere之数据分片策略

    千次阅读 2021-09-02 21:45:47
    跟我学ShardingSphere之数据分片策略

    在前面一篇《跟我学ShardingSphere之SpringBoot + ShardingJDBC分库》我们介绍了如何利用ShardingJDBC进行分库,用到了inline行表达式分片策略,ShardingSphere还有其他几种分片策略,下面我们来介绍一下

    分片键

    用于分片的字段,是将数据库或表拆分的字段,比如,我可以使用user_id作为分片键将用户数据分到不同的表中,这里的user_id就是分片键,除了这种单字段分片,ShardingSphere还支持多个分片字段。SQL中如果没有分片字段,将执行全路由,也就是会把SQL发送到所有的数据分片上执行,性能较差。

    分片算法

    分片算法描述的是如何进行分片,需要结合分片键使用,比如我需要使用user_id对2取模进行分表,那么这里取模就是分片算法,ShardingShpere支持>、<、=、IN和Between分片。这些分片算法需要根据实际的业务开发,ShardingSphere没有默认的分片算法,所以你得根据自己的业务来开发自己的分片算法,不过也挺简单的,ShardingSphere已经预留好了对应的接口,你实现对应的接口就好了

    目前ShardingSphere将常用的分片算法进行抽象,定义了四种分片算法

    1、精确分片算法

    对应PreciseShardingAlgorithm,用于处理使用单一键作为分片键的=与IN进行分片的场景。需要配合StandardShardingStrategy使用。

    2、范围分片算法

    对应RangeShardingAlgorithm,用于处理使用单一键作为分片键的BETWEEN AND、>、<、>=、<=进行分片的场景。需要配合StandardShardingStrategy使用。

    3、复合分片算法

    对应ComplexKeysShardingAlgorithm,用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度。需要配合ComplexShardingStrategy使用。

    4、Hint分片算法

    对应HintShardingAlgorithm,用于处理使用Hint行分片的场景。需要配合HintShardingStrategy使用

    分片策略

    包含分片键和分片算法,由于分片算法的独立性,将其独立抽离。真正可用于分片操作的是分片键 + 分片算法,也就是分片策略。目前提供5种分片策略

    1、标准分片策略

    对应StandardShardingStrategy。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法。PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。RangeShardingAlgorithm是可选的,用于处理BETWEEN AND, >, <, >=, <=分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理。

    2、复合分片策略

    对应ComplexShardingStrategy。复合分片策略。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。

    3、行表达式分片策略

    对应InlineShardingStrategy。使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发,如: t_user_$->{u_id % 8} 表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0到t_user_7。

    4、Hint分片策略

    对应HintShardingStrategy。通过Hint指定分片值而非从SQL中提取分片值的方式进行分片的策略

    5、不分片策略

    对应NoneShardingStrategy。不分片的策略。

    分片示例

    我们还是通过一个分表的示例来演示一下,如何根据自己的需求来开发自己的分片算法

    需求:业务上存在多个分支机构,需要将不同分支的客户拆分到不同的表

    分析:通过需求可知,这是个单分片的需求,我们选择标准分片就可以满足需求

    1、先建表

    CREATE TABLE `tb_cust` (
      `cust_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
      `cust_name` varchar(20) NOT NULL COMMENT '用户名称',
      `branch_id` char(3) NOT NULL COMMENT '分公司',
      `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
      PRIMARY KEY (`cust_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=202 DEFAULT CHARSET=utf8 COMMENT='客户信息表';
    

    按不同的分支机构建不同的表

    在这里插入图片描述

    从表名可以看出来,我们有fc5、fdg、fdm、fdw这几个分支机构

    2、分片算法

    标准分片策略需要实现PreciseShardingAlgorithm接口

    /**
     * 精确分片算法(可用于分库、分表)
     * 公众号【Java天堂】
     */
    public class BranchPreciseShardingAlgorithm implements PreciseShardingAlgorithm<String> {
        @Override
        public String doSharding(Collection<String> shardingNameList, PreciseShardingValue<String> preciseShardingValue) {
            String key = preciseShardingValue.getValue();
            //遍历所有的数据分片,与分片键(key)比较,匹配就返回当前数据分片
            for(String shardingName : shardingNameList){
                if(shardingName.endsWith(key.toLowerCase())){
                    return shardingName;
                }
            }
            throw new IllegalArgumentException();
        }
    }
    

    3、分片策略配置

    server:
      port: 8090
    
    spring:
      main:
        allow-bean-definition-overriding: true
    
      shardingsphere:
        datasource:
          names: testdb0,testdb1
          testdb0:
            type: com.zaxxer.hikari.HikariDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            jdbc-url: jdbc:mysql://localhost:3306/testdb0?useUnicode=true&characterEncoding=utf-8
            username: root
            password: 123456
          testdb1:
            type: com.zaxxer.hikari.HikariDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            jdbc-url: jdbc:mysql://localhost:3306/testdb1?useUnicode=true&characterEncoding=utf-8
            username: root
            password: 123456
    
        # 分库、分表配置
        sharding:
          tables:
            tb_cust:
              actual-data-nodes: testdb0.tb_cust_$->{['fdg','fc5','fdw','fdm']}
              # 分表配置
              table-strategy:
                standard:
                  sharding-column: branch_id
                  precise-algorithm-class-name: com.kxg.shardingRule.BranchPreciseShardingAlgorithm
    
        props:
          sql.show: true
    

    从上面的配置可以看出来,我们分表的策略不再是inline,而是换成standard,表示标准分片策略

    分片策略也换成了我们自己写的分片算法:BranchPreciseShardingAlgorithm

    @Data
    @TableName("tb_cust")
    public class Cust {
        private Long custId;
        private String custName;
        private String branchId;
    }
    
    public interface CustMapper extends BaseMapper<Cust> {
    
    }
    
    @Service
    public class CustService {
        @Autowired
        private CustMapper custMapper;
    
        public void insert(Cust cust){
            int count = custMapper.insert(cust);
            System.out.println("insert count:" + count);
        }
    
        public Cust getCust(Long custId){
            return custMapper.selectById(custId);
        }
    }
    
    @RestController
    public class CustController {
        @Autowired
        private CustService custService;
    
        @RequestMapping("/cust/add")
        public String addUser(@RequestBody Cust cust){
            custService.insert(cust);
            return "ok";
        }
    
        @RequestMapping("/cust/get")
        @ResponseBody
        public Cust getUser(Long custId){
            return custService.getCust(custId);
        }
    }
    

    启动程序,可以看到如下打印:

    tables:
      tb_cust:
        actualDataNodes: testdb0.tb_cust_$->{['fdg','fc5','fdw','fdm']}
        logicTable: tb_cust
        tableStrategy:
          standard:
            preciseAlgorithmClassName: com.kxg.shardingRule.BranchPreciseShardingAlgorithm
            shardingColumn: branch_id
    

    表示已经加载配置成功

    我们试着添加两个Cust信息,如下
    在这里插入图片描述
    在这里插入图片描述
    我们可以看到控制台打印的SQL语句:

    Logic SQL: INSERT INTO tb_cust  ( cust_id,cust_name,branch_id )  VALUES  ( ?,?,? )
    Actual SQL: testdb0 ::: INSERT INTO tb_cust_fdg  ( cust_id,cust_name,branch_id )  VALUES  (?, ?, ?) ::: [1, 客户-FDG, FDG]
    
    Logic SQL: INSERT INTO tb_cust  ( cust_id,cust_name,branch_id )  VALUES  ( ?,?,? )
    Actual SQL: testdb0 ::: INSERT INTO tb_cust_fc5  ( cust_id,cust_name,branch_id )  VALUES  (?, ?, ?) ::: [2, 客户-FC5, FC5]
    

    从执行的SQL可以看到,是根据我们的预期进行分表操作的,下面去数据库对应的表查看一下对应的数据是不是正确插入
    在这里插入图片描述

    可以看到,两次的数据根据不同的branchId字段插入到不同的表中,达到了根据branchId分表的目的

    如果感觉对你有些帮忙,请收藏好,你的关注和点赞是对我最大的鼓励!
    如果想跟我一起学习,坚信技术改变世界,请关注【Java天堂】公众号,我会定期分享自己的学习成果,第一时间推送给您

    在这里插入图片描述

    展开全文
  • mongodb分片

    千次阅读 2020-02-03 14:00:08
    什么是mongodb分片,有什么作用? mongodb分片就是将大型集合分割到不同的服务器上,它可以自动且均衡的分配数据。它一般是针对特别大的需求,比如一个集合需要非常的大,几百个G。分片到10个服务器之后,每个...
  • Redis集群数据分片机制说明

    千次阅读 2020-03-24 15:53:15
    为了使得集群能够水平扩展,首要解决的问题就是如何将整个数据集按照一定的规则分配到多个节点上,常用的数据分片的方法有:范围分片,哈希分片,一致性哈希算法和虚拟哈希槽等。 范围分片假设数据集是有序,将顺序...
  • 闲谈IPv6-IPv6的分片(IPv6 Fragment)

    万次阅读 多人点赞 2019-03-09 08:36:30
    熟悉IPv4的肯定知道IP分片这个特性,它在某种意义上让应用程序忘记了数据包还有大小这个属性,也就是说,应用程序可以发送小于IP头规定的最长65535字节的任意大小的数据包。 IPv4严格采纳分层模型,让路径MTU这种事...
  • 大文件分片上传

    千次阅读 2019-06-16 21:51:33
    最近在做公司的app项目,其中的一块需求是要上传视频,由于现在的电子设备等像素都比较高,所以拍摄的视频内存都比较大,如果直接上传很容易出现连接超时,在查询相关资料之后,准备在前端实现分片上传,其原理就是...
  • Clickhouse副本与分片

    千次阅读 2020-11-21 00:50:51
    一 副本与分片概述 副本是指两个相同数据的表,作用是为了数据备份与安全 分片是指不同的服务器存储同一张表的不同部分,作用是为了水平切分表,缓解单一服务的压力. 针对于副本的需求,有两种不同的方式,后面会一一概述...
  • Elasticsearch 6.6 官方文档 之「索引分片分配」

    千次阅读 多人点赞 2019-05-14 15:18:12
    在本模块中,提供每个索引的设置,以控制分片到节点的分配: - [分片分配过滤](https://www.elastic.co/guide/en/elasticsearch/reference/current/shard-allocation-filtering.html):`Shard allocation filtering...
  • HTTP方式文件分片断点下载

    千次阅读 2019-05-11 12:05:25
    在进行大文件或网络带宽不是很好的情况下,分片断点下载就会显得很有必要,目前各大下载工具,如:迅雷,都是很好的支持分片断点下载功能的。本文就通过http方式进行文件分片断点下载,进行实战说明。 HTTP之Range...
  • Wireshark捕获IP报文——分片与不分片

    千次阅读 2020-12-31 00:24:46
    Wireshark捕获IP报文——分片与不分片Wireshark操作一、观察不分片标志对较短IP报文传输的影响Windows命令行提示窗口Wireshark二、观察不分片标志位对较长IP报文传输的影响Windows命令行提示窗口三、将IP报文分片...
  • MongoDB分片集群介绍以及安装

    千次阅读 2019-05-02 16:49:15
    文章目录架构概述分片集群原理分片集群搭建环境准备mongs路由安装配置服务器可复制集安装分片集群安装分片1、分片3安装分片2安装初始化两个可复制集分片配置针对集合分片启动和停止命令分片注意点和建议 架构概述 ...
  • 上一篇我们介绍了 sharding-jdbc 的基础概念,还搭建了一个简单数据分片的案例,但
  • 本文将重点分析ElasticJob的分片机制: ElasticJob分片工作机制: 1、ElasticJob在启动时,首先会启动是否需要重新分片的监听器。 代码见:ListenerManager#startAllListeners {…; shardingListenerManager....
  • MongoDB 4.2.0分片集群搭建

    万次阅读 热门讨论 2019-09-05 17:33:57
    MongoDB分片集群搭建 一.环境介绍 系统环境 操作系统 主机名 IP地址 CentOS Linux release 7.6.1810 (Core) mongox 10.0.0.4 CentOS Linux release 7.6.1810 (Core) mongoy 10.0.0.5 CentOS Linux ...
  • MySQL的分片(二)——MySQL分片

    万次阅读 2018-10-18 14:25:34
    第一,了解MySQL分片可以更合理地定制分片策略,选分片字段是要讲科学的。 第二,了解MySQL分片以后如果出现故障报错,也有助于问题的排查。 第三,关系到开发过程中的代码调整,做分片后的MySQL数据库操作受到...
  • 当我们在使用shard key切分时,默认是Mongos自动分片,自动设定切分规则。但是我们也可以手动指定分片规则。在后面的一篇博客《MongoDB4.0 Sharded Cluster+Replica Set集群搭建》详细介绍了MongoDB集群的搭建方法,...
  • 数据库分片(Database Sharding)详解

    万次阅读 2019-04-20 06:52:00
    Introduction 导言 任何看到显著增长的应用程序或网站,最终都需要进行扩展,以适应流量的增加。以确保数据安全性和完整性的方式进行...在这篇概念性文章中,我们将讨论一种“可动态扩展的”数据库架构:分片数据...
  • 副本数量的选定原则 对于副本数,比较好确定,可以根据我们集群节点的多少与我们的存储空间决定,我们的集群服务器多,并且...#在一个三节点组成的集群中 设置一个主分片数为5,副分片为0的索引 PUT /haizhi1 { "s...
  • 1 MyCat分片规则 数据切分中重要的几条原则,其中有几条数据冗余,表分组(Table Group)。 1.1全局表 如果你的业务中有些数据类似于数据字典,比如配置文件的配置,常用业务的配置或数据量不是很大,很少变动...
  • 大文件分片上传前后端实现

    千次阅读 2020-11-17 21:30:54
    /** * 大文件分片上传 * @param name 文件名 * @param md5 文件MD5值 * @param size 文件大小 * @param chunks 总的分片数 * @param chunk 当前分片数 * @param multipartFile 分片流 * @throws IOException */ @...
  • 以太坊分片Sharding FAQ

    千次阅读 2018-06-10 15:37:39
    一个典型的例子是货币转账,货币可以从分片i转移到分片j,首先在分片i中创建一个”借记“交易来销毁代币,然后在分片j中创建一个”贷记“交易来创建代币,并将借记交易的收据作为贷记证明是合法的。 但是CAP...
  • ShardingSphere 数据分片

    千次阅读 2019-05-24 17:25:37
    其实很多人对分库分表多少都有点恐惧,其实我也是,总觉得这玩意是运维干的、数据量上来了或者sql过于复杂、一些数据分片的中间件支持的也不是很友好、配置繁琐等多种问题。 我们今天用ShardingSphere 给大家演示...
  • 区块链扩容方案之—分片(sharding)分片背景分片思想:分而治之分片策略(分类)潜在挑战:1.网络分片(Network sharding)2.交易分片(transaction sharding)3.状态分片(state sharding)总结 分片背景   今天...
  • 文件分片上传【前端】

    千次阅读 2019-09-30 11:30:31
    闲话少说,直接进入今天的正题,文件的分片上传。 先介绍一下文件的分片上传。 1、分片上传的原理 分片上传功能是将一个文件切割为一系列特定大小的小数据片,分别将这些小数据片分别上传到服务端,全部上传完...
  • MyCat分片规则之自定义范围分片

    千次阅读 2019-09-04 21:06:48
    实现方式:范围分片,就是我们自己根据某个字段的数值范围来确定这些数据到底存放在哪一个分片上,不过需要我们提前规划好分片字段某个范围属于哪个分片。切分规则根据文件(autopartition-long.txt)配置的范围来进行...
  • 分片上传及断点续传原理深入分析及示例Demo

    万次阅读 多人点赞 2019-02-23 14:47:39
    分片上传、断点续传,这两个名词对于做过或者熟悉文件上传的朋友来说应该不会陌生。之所有有这边文章,还是因为自己在网上浏览了一些文章后发现没有找到一篇能瞬间明白原理和实现的,因此决定自己写一篇文章,方便有...
  • elasticsearch查询某个索引分片信息

    万次阅读 2019-10-30 14:19:53
    elasticsearch6.8 ...通过下面的路径可以查询elasticsearch某个索引分片信息 http://xx.xx.xx.xx:9200/索引名称/_search_shards { "nodes": { "Q6i1duFYQLmJFIu812DQjQ": { "name": "node1", "ephemera...
  • Vue中实现视频的分片上传

    千次阅读 2019-11-19 10:51:05
    第三步:readChunkMD5() 方法:分片并上传,其中uploadChunk为上传方法 // 针对每个文件进行chunk处理 const readChunkMD5 = () => { // 针对单个文件进行chunk上传 for (var i = 0; i ; i++) { const { ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 477,383
精华内容 190,953
关键字:

分片