美文网首页MySQL
MySQL之水平分表取模算法

MySQL之水平分表取模算法

作者: 隔岸坐看云卷云舒 | 来源:发表于2019-04-01 15:42 被阅读112次

在我们业务中,在并发很高的IO下,往往是需要水平分表(分库)或者是垂直分表(分库)。
本文,就详细介绍水平分表之取模算法:

假设一个场景,APP需要手机号登录或者注册,而一张用户表中已经有千万级的数据,单表的IO读写已经很吃力,需要迫切的分表,那么该如何分表,以什么形式去分

分表方法:
1.取模算法
2.哈希算法
3.范围分表

本文针对水平分表的取模算法来分析:

1.取模实际上就是对被除数进行取余的操作 A%B=余数
2.利用用户手机尾号进行求余的操作
3.假如我们水平分表5张表,那么求余公式则为尾号/5=余数
4.这个余数就是我们的表名,进而得出该用户信息应该在哪张表
5.业务直接去以余数命名的该表查询信息

原始业务图解:


WechatIMG489.jpeg

将要实现的:


WechatIMG490.jpeg

开始实践:

我们将用户表设计为5张表 从user_0....user_4;

表结构如下:

WechatIMG488.jpeg

字段name即为手机号

在上期中,我们了解了负载均衡与消息队列,我们这次将请求还是与之前的结合起来

producer项目里创建controller

public function AddUser():void {
        $data['name'] = time();
        $json = json_encode($data);
        dispatch(new UserJob($json))->onQueue('User');
    }

`
将当前时间戳模拟为用户手机号,并推入到RabbitMQ

consumer项目的队列消费者进程开始消费

public function handle(){
        $data = json_decode($this->data,true);
        $table = 'User_'.$data['name']%5;
        $tableObj = $this->tableObj($table);
        $tableObj->name = $data['name'];
        $tableObj->save();
    }

    /**
     * 通过反射返回Model对象
     * @param $class_name
     * @return object
     * @author mjShu
     * @throws \ReflectionException
     */
    private function tableObj($class_name){
        $class_name = 'App\Http\Model\\'.$class_name;
        $class = new \ReflectionClass($class_name);
        $obj = $class->newInstance();
        return $obj;
    }

handle方法里,我们通过对producer生产的数据中的模拟手机号进行求余
得到余数,通过字符串拼接得到表名,表名等于User_余数

进而通过PHP的反射机制实例化Model类,将其保存进表

启动AB测试
ab -c 100 -n 2000 http://192.168.2.101/user

RabbitMQ消费后通过Lumen队列插入数据库
启动horizon,应该如图

WechatIMG485.jpeg

RabbitMQ ACK确认完毕后,我们来查看下表:

WechatIMG486.jpeg

由此可见,我们的数据均是是被水平均匀的拆分到5张表中,怎么样,是不是很简单呢,原理就是通过求余来确定数据的落表地点,进而直接查询该表,均匀打散了数据,并且有规律可循,避免了单表的压力过大,相同理论,该分表方法也可以运用到其他方面,本文只是做一下探讨,实际上求余的操作,都是由中间件完成,不应该放在业务中,因为太繁琐,比如查询某个日期的数据,必须每张表都要执行查询最终合并结果集返回

相关文章

  • MySQL之水平分表取模算法

    在我们业务中,在并发很高的IO下,往往是需要水平分表(分库)或者是垂直分表(分库)。本文,就详细介绍水平分表之取模...

  • javascript运算符

    算术运算符 如 + , - , * , / , % , ++ , -- % 表示取余或取模 ++ 表...

  • redis实现全局唯一id

    背景 新公司用mysql开发,对于建表什么的规定特别严格,主键id必须是自增,但是取模分表的过程中,id是不能重复...

  • mysql分区

    mysql分区 Mysql支持水平分区,并不支持垂直分区;水平分区:指将同一表中不同行的记录分配到不同的物理文件中...

  • Mysql 相关

    MySQL索引 MySQL索引背后的数据结构及算法原理 覆盖索引和回表操作 MySQL性能优化 MySql表分区详...

  • 常用算法

    1、一致性 Hash 算法 2、取模法 3、复制均衡算法

  • redis数据分布算法

    1.hash算法,数据取模 最大的问题,当一台宕机的时候,原来对3取模,变成对2取模,可能会打到不同的机器上去。 ...

  • Mysql常见水平分表方案

    根据经验,Mysql表数据一般达到百万级别,查询效率会很低,容易造成表锁,甚至堆积很多连接,直接挂掉;水平分表能够...

  • 快速幂取模算法

    算法简介 快速幂取模算法是在o( logn )的时间内求得 a ^ b % n的值 先证明结论:a*b % c =...

  • 快速幂取模算法

    前言 在算法程序设计竞赛中,我们竞赛选手会经常碰到对某个数N进行求大数次幂并对1e9+7取模的运算的题目,一方面求...

网友评论

    本文标题:MySQL之水平分表取模算法

    本文链接:https://www.haomeiwen.com/subject/lcyvbqtx.html