[数据库]-----记一次mysql分库的操作(冷热分离)

前提:

1.原有库是mysql数据库,已经根据用户pin分片
2.每片是一主两从
3.主表已经分过表了
4.数据库所在服务器为4C8G
5.库中数据量已经超过千万,而且以每天3万多的数据持续增长,将来每天或许会更多
6.库内数据为订单数据,每时每刻都有新的订单产生,每个订单都要经历多个状态的变化,最终变成完成状态,每次变化状态,都会对数据库进行修改

正题:

现在这样的数据库,其实是完全可以支持现有业务,但考虑到以后随着数据量的日益增长,每次查询都要在千万数据中查找,但其实大部分查询,都是查最近的数据,历史数据几乎不查询,基于这个条件,就考虑到可以做个分库,也就是冷热分离。

所谓冷热分离,网上有很多说法,而我之所以做冷热分离,最终目的,就是为了将经常使用查询的数据放在生产库中,而查询不多的历史数据就放在历史库中,这样既可以保证数据的完整,也可以减轻生产库的压力。

既然有这样的分库查询,那就涉及到两个库的数据同步(这里叫生产库和历史库)
生产库放的是热数据,历史课放冷数据

正常下单后,订单数据还是添加到生产库中,但是每次数据在生产库的变化,都会多发一个mq出去,mq中带有这个订单数据的唯一主键和订单所改变的状态

历史库接收到这个mq,再反查生产库,获得这条数据,然后在历史库做相应的状态更改,这样就可以保证历史库和生产库的数据统一

如下图:

这里写图片描述


对于生产库,原则上只保留500万左右的热数据,其余历史数据,全部放在历史库,这样又会有两个重点:数据迁移和多数据源的查询

1.数据迁移

以下提供几种数据迁移的思路
1.1.执行一个job,定时每天凌晨开始自动迁移,每次迁移若干条,这样就会在不知不觉中将数据迁移完,这样最保险,但不是效率最高
1.2.直接用一个线程池,最多开五个线程(具体能开几个,看自己的机器性能),然后每个线程每次只跑一天的量,这样其实也是很快的

2.多数据源的查询

有了两个数据源,那么什么时候查生产库,什么时候查历史库就是需要考虑的一个问题,我这边完全是业务方面的区分,这里只提一嘴,供参考
2.1.针对单条数据的查询,单条数据的查询一般发生在刚刚下单后,所以优先查询生产库,生产库没有,再去查询历史库。
2.2.针对某一时间段内,多条数据查询list,这里我们可以预先定义一个分割线,这个分割线是一个日期,这个日期就是生产库最早一条数据的日期,有了这个分割线,那我们只需要拿要查询的日期区间和这个分割线做比较,即可确定
2.3.针对多个分散订单的查询list,理论上没有任何规律,但是由于历史数据发现,这种情况一般有数量不多,数据多在近期的特征,所以还是优先查询生产库,查不到再查询历史库

思考

这个冷热分离的好处,就是将不常用的数据放在历史库中,当然,这个历史库也可以是多个,也就是一个生产库,多个历史库,每个历史库都存放某一时间段的数据

扩展

作为思考,如果以后每天的数据量都很大,我将考虑在数据库之前加一层缓存,比如用redis等非关系型数据库,或者用es,因为以前也尝试过用这样的方式来缓解数据库的压力,但发现会存在低几率的数据丢失,所以在这些又会涉及到数据的准确性,数据的即时同步将会是一个很大的挑战,但这应该是现有技术中,对于上亿级别的数据即使查询,比较好的方式了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499890.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用OC进行iOS截屏,同时保证清晰度

一般情况下我们使用如下代码进行截屏:UIWindow *screenWindow [[UIApplication sharedApplication] keyWindow]; UIGraphicsBeginImageContext(screenWindow.frame.size); [screenWindow.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *screenIm…

[python]---从java到python(02)---多线程,队列

多线程测试 #!/usr/bin/env python # -*- coding:utf-8 -*-import threading import timeclass A(threading.Thread):def __init__(self):# 初始化改线程threading.Thread.__init__(self)def run(self):# 该线程要执行的程序内容for i in range(3):print("我是线程A&quo…

将iOS默认上下文坐标系改变为Quartz通常坐标系

由于iOS的UIKit默认的坐标系的原点处于视图的左上角,而Quartz的通常坐标系中的原点位于左下角。当我们使用UIKit的坐标操作CGContextRef的时候,绘制出来的图片是上下颠倒的。因此我们在使用Qaurtz处理图形的时候,往往需要将坐标系转为与Quart…

[python]---从java到python(03)---爬虫

1.简单网页 #!/usr/bin/env python # -*- coding:utf-8 -*-import urllib.requestfile urllib.request.urlopen("https://www.jd.com") data file.read() # dataline file.readline() print(data)fhandle open("E:/python/1_1.html", "wb"…

iOS网络请求认证挑战

一、引言 Http请求中认证挑战相关的代理如下: 1.将要发送一个认证挑战的请求 - connection:willSendRequestForAuthenticationChallenge:2.是否能够对一个保护空间进行认证(已废弃)- connection:canAuthenticateAgainstProtectionSpace:3.…

大数据相关整理

1.hdfs 1.1.namenode 所有文件的读写入口,用来保存文件的元信息 元信息包括: fsimage文件:文件权限信息文件在block块的偏移量文件的位置信息 editlogs文件:对文件的写操作日志文件写日志指令,为了安全同步&#xf…

OC编码规范

一、命名规范 1.类: (1)首字母大写,后续单词首字母大写。 (2)类名末尾要包含此类的类型,比如RootView,RootViewController。 2.属性 (1)属性名称首字母小写,后续首字母大写; (2)使用property,要保持必要的空格&#xf…

数据库---mysql的索引和引擎

mysql 的索引和引擎 mysql的数据都是存放在磁盘上的,都说索引会使查询变快,那么肯定是索引用了特殊的数据结构。 常见的数据结构有: hash hash就是咱们在hashMap中的那个hash,用hash确实快,而且时间复杂度是O&#x…

SQLite内置表SQLITE_MASTER

一、概述1.SQLite数据库中有一个内置表,名为SQLITE_MASTER,此表中存储着当前数据库中所有表的相关信息,比如表的名称、用于创建此表的sql语句、索引、索引所属的表、创建索引的sql语句等。2.SQLITE_MASTER表示只读的,只能对他进行…

redis单线程为什么还快的个人解释

面试的时候, 面试官问,redis是单线程还是多线程 答:单线程 面试官再问,单线程,为什么还快呢?不应该是多线程才更快吗?那这是不是有什么矛盾啊? 答:啊?&#x…

CDN的实现原理

一、传统模式 在描述CDN的实现原理前,让我们先看传统的未加缓存服务的访问过程,以便了解CDN缓存访问方式与未加缓存访问方式的差别: 用户提交域名→浏览器对域名进行解释→得到目的主机的IP地址→根据IP地址访问发出请求→得到请求数据并回复…

数据库---事务的隔离级别

首先,我们下面说的数据库事务,都是使用INNODB引擎的结果。 MYISAM是没有事务的,也就没有下面这些说法。 1.数据库事务的四大特性: 原子性:事务包含的所有数据库操作要么全部成功,要不全部失败回滚一致性&…

iOS崩溃日志收集

一、概述iOS-App崩溃分为两种,一种是异常:NSException,一种是信号:Signal。二、异常崩溃1.NSException对象(1)reason:崩溃原因。(2)callStackSymbols:调用堆栈。(3)name:崩溃名称(4)userInfo&am…

统计iOS项目代码行数

打开终端,输入如下命令:find . -name "*.m" -or -name "*.h" -or -name "*.xib" -or -name "*.c" | xargs wc -l 此命令会迭代子目录,会统计每个源代码文件行数及总数,统计的行数包含空…

一个简单的权限系统模型

我们知道,一般说的简单的权限系统,都是使用shiro或者spring-security shiro之前用的比较多,原理也容易理解,算是比较成熟的权限方面的框架spring-security相对源码比较难懂,但由于与spring的完美融合,也有…

获取iOS任意线程调用堆栈(一)获取任意线程的调用栈地址列表

转载自:http://blog.csdn.net/jasonblog/article/details/49909163 如果要获取当前线程的调用栈,可以直接使用现有API:[NSThread callStackSymbols]。 但是并没有相关API支持获取任意线程的调用栈,所以只能自己编码实现。 1. 基础…

linux---基础01

Linux是一种自由和开放源码的操作系统,存在着许多不同的Linux版本,但它们都使用了Linux内核。Linux可安装在各种计算机硬件设备中,比如手机、平板电脑、路由器、台式计算机 Linux的目录结构 bin (binaries)存放二进制可执行文件 boot 存放用…

获取iOS任意线程调用堆栈(二)符号化理论:Mach-o文件结构

我们知道Windows下的文件都是PE文件,同样在OS X和iOS中可执行文件是Mach-o格式的。 所以我们如果要进行逆向分析,首先要熟悉Mach-o文件结构。 Mach-o包含三个基本区域: 头部(header structure)。 加载命令(…

linux---基础02

二、用户、组管理命令 Linux采用组来组织和管理用户 在Linux中每个用户有唯一的用户标识符UID,该UID是一个无符号整数。 同时每个用户也必须至少属于一个组,也有组标识符GID。 其中UID与GID独立编号。 1. groupadd命令 (1)grou…

获取iOS任意线程调用堆栈(三)符号化理论:从Mach-o结构分析类名方法名

下面来讲讲如何从Mach-o文件中分析出类名和方法名,也让我们了解下class-dump的原理。 Mach-o结构有两个节:__objc_classname 和 __objc_methname 其中就是类名和方法名。 其中__objc_classname的偏移为:ox7961 __objc_methname的偏移为0x6…