「论道架构师」拒绝无脑搬砖,从分库分表开始

程序员的工资是不是太高了?真相让人心疼 2018互联网冬季其中一个原因是认为劳动力成本太贵???? 今年一场突如其来的寒流袭击了互联网行业,使大爆发了4年之久的互联网行业也迎来了寒冬。很多大公司都在调岗或者裁人。 纵观互联网的寒冬,原因定位很明确,市场也是到了该规范的阶段了。这是所有大爆发后的正常轨迹。大爆发让企业共注重盈利和用户数据,而无暇更多顾及用户感受和用户的真正需求。然而,有的创业公司老板却在失败后抱怨着其中一个原因:劳动力成本太高。还有很多网上吃瓜群众到处说着:程序猿工资高,程序猿跟其他岗位薪资相差太大了。不公平。在这里,博主找到一篇很 阅读详情

「论道架构师」拒绝无脑搬砖,从分库分表开始

事件起因

6月初我负责的商家数据某功能由于业务原因导致数据量不断上涨,当时使用的MySQL单表已经难以提供高效的查询,因此基于商家维度(商家主键ID)对它进行了分表,问题得以解决。

6月中旬我沉浸在无止尽的需求之中,边做边发出感慨:进大厂又能怎么样呢,还不是CRUD,面试造火箭罢了。

此时,架构师笑了笑,于是乎有了本篇文章。

我的方式:取模水平分割

亮架构:说一下你上次分表的实现方案吧,Kerwin。

我:我是参照其他系统的方式进行的,利用商家主键Id(商家系统自增的Long型主键)对100取模,由此计算出它应该落在哪一张表,唯一的变动就是这个环节以及数据迁移了。

大概思路如下:

// 业务层代码...
String tableName = "orgcode_datas_" + orgcode % 100;
String insertUserSql = "INSERT INTO " + tableName + " VALUES ('" ... "');"; 

亮架构:所以你采用的就是最简单的方式,而且还把取模逻辑耦合在了业务层吗?

我:是啊,其他系统也都是这么做的,这样搞最快,最安全。

亮架构:你的系统用的是MyBatis对吧,你稍微调研一下就知道,我们可以借助MyBatis的拦截器实现刚刚业务代码中耦合取模的那部分逻辑,虽然本质上没有高明多少,但让它的数据操作底层变得更加清晰明了了,这不就是一种进步吗?

我(略感羞愧):你说的有道理,回去我研究研究。

亮架构:再来看另一个问题,你说了这次分表涉及到数据迁移,你现在分了100个表,万一以后还不够用怎么办?难道要再全部迁移一遍吗?

我(非常羞愧):啊这个,应该不会不够用吧…

一致性哈希方案

亮架构:Kerwin,你面试的时候有没有被问到过Redis的一致性哈希问题?

我(来劲了):有,Redis中引入了一致性Hash算法。该算法对2^32 取模,将Hash值空间组成虚拟的圆环,整个圆环按顺时针方向组织,每个节点依次为0、1、2…2^32-1,之后将每个服务器进行Hash运算,确定服务器在这个Hash环上的地址,确定了服务器地址后,对数据使用同样的Hash算法,将数据定位到特定的Redis服务器上。如果定位到的地方没有Redis服务器实例,则继续顺时针寻找,找到的第一台服务器即该数据最终的服务器位置。

image-20210704155443807.png

亮架构:Redis的这个知识点你知道,MySQL的你就不知道了?如果我让你把简单取模法更换为一致性哈希方案,你该怎么做?

我(忐忑):如果参考Redis的话,我会这么做:

  1. 从表的命名开始,尽量取名为取模后相对均匀的名称,不以连续后缀结尾了
  2. 我需要找一个碰撞相对较少的哈希算法
  3. 取模的逻辑需要修改为两步,首先是建立数据表落点(即上图中的蓝球)并存储,再计算数据的落点(即红球),然后动态的计算它应该归属到哪一张表即可

亮架构:差不多,命名的部分可以再思考思考,但是你知道你这么做会遇到什么问题吗?提示:和Redis一样的问题。

我(信心满满):这个我知道,可能会出现数据过于集中的问题,这是由于数据和服务器分布不均匀导致的,例如上图中的情况,归属到一号服务器(顺时针第一个蓝球)的概率太大了,这个简单,我们只需要增加虚拟节点,或者从命名上考虑让它尽量平铺,均匀就好啦。

亮架构:孺子可教也,你说说看,这个方式和你刚刚的方式耗费的精力,优劣对比吧。

我(不好意思):从精力上讲,一致性哈希方案多了一步二次计算位置的动作,但是按您说的,如果我们在拦截器中去实现这一步动作的话,整体都是无感知的,只是多了一个方法而已,而从扩展性来讲,那就好多了,无论是增加节点还是减少节点,我们只需要迁移的对应的数据节点即可。

Tips:如下图中,如果我们增加了第四个服务器节点,第四个服务器节点的数据来源只可能是第一个服务器节点

image-20210704162853406.png

Range方式分表

亮架构:那我再考考你,假如让你去订单组,对订单快照或者说订单流水进行分表,你怎么做?

我(思考状):订单流水信息有一个明显的不同点在于它的主键Id是一个真正的无意义自增长整型,刚才提到的方式是可行且通用的,但是针对这种特殊场景,我会采用分段分表的方式,比如 1 - 100万为表1,100万01到200万为表2,以此类推,反正这个表只有插入和按Id查询,至于按订单人查询的功能,其他模块就满足了,不用我考虑。

我(瞬间反应过来):不对啊,那订单流水Id基于什么获取呢?我们都要分表了,难道用自增Id?

亮架构:你能想到这一点还挺好的,现在有很多分布式算法都可以解决这种问题,比如Twitter的分布式自增ID算法(Snowflake)、Redis的incr命令、百度的uid-generator算法等等,很好,你也有一点程序员的样子了,知道反问了。

把上述知识总结抽象,你能得到什么?

亮架构:你刚才提到了很关键的一点,你说你之所以用最简单的水平分割方式去处理,是因为其他系统的代码也都是这么写的?

我:是的,所以我就把它们复制粘贴,改了一下。

亮架构:OK,你看,无论是简单的水平取模方式,还是一致性哈希,亦或是Range方式,它的本质都是:SQL解析 =》SQL重写 =》 路由 =》 数据库执行 =》 结果返回,

不同点在于,几个方案的路由策略不一样而已,你把这些东西抽象成可配置化的解决方案,放到咱们的Lib库中,以后别人再用的时候是不是就没那么麻烦了?

我:是的,既省时间,又省精力,只要咱们都用的是Mybatis和MySQL就行。

亮架构(扶额):你再想想…

我(思考状):对,是我狭隘了,我们刚刚所说的策略根本不用在乎是什么数据库,是什么ORM框架,无论是MongoDB也好,MySQL也罢,它真正的流程就那么几步,我只需要依赖Spring体系,获取到数据库连接信息,然后重写SQL为它分配路由即可。

亮架构(笑了笑,起身走了):孺子可教也,你还觉得每天都是CRUD了吗?明明有一个研究和学习的机会放在你的面前,是你自己选择了最简单的方式,因为你既追求速度,又害怕出问题,所以你用了和前人一样的方式来解决这个问题,工作中很难遇到造火箭的机会,但是造个自行车,哪怕是车轮,也是挺好的吧,认真学习,以后要抓住机会啊。

我看着架构师远去的背影,心中无比的激动,感谢他把本可以摸鱼的时间拿来教导我(手动狗头🤪)。

最近把一些好的学习资料都整理出来,免费分享给大家 ,文末有获取方式哦

包含:JVM,JAVA集合,网络,JAVA多线程并发,JAVA基础,Spring原理,微服务,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存等等

image

基础篇


点击免费领取我的学习笔记:学习视频+大厂面试真题+微服务+MySQL+Java+Redis+算法+网络+Linux+Spring全家桶+JVM+学习笔记图

JVM 篇


MySQL 篇


点击免费领取我的学习笔记:学习视频+大厂面试真题+微服务+MySQL+Java+Redis+算法+网络+Linux+Spring全家桶+JVM+学习笔记图

SpringBoot应用篇@Value配置自动刷新能力扩展实践 在我们的日常开发中,使用@Value来绑定配置属于非常常见的基础操作,但是这个配置注入是一次性的,简单来说就是配置一旦赋值,则不会再修改; 通常来讲,这个并没有什么问题,基础的 SpringBoot 项目的配置也基本不存在配置变更,如果有使用过 SpringCloudConfig 的小伙伴,会知道@Value可以绑定远程配置,并支持动态刷新 接下来本文将通过一个实例来演示下,如何让@Value注解支持配置刷新;本文将涉及到以下知识点 BeanPostProcessorAdapter + 自定义注解:获取支 阅读详情

相关推荐

后端一次给你10万条数据,如何优雅展示,面试官到底考察我什么?

背景 面试题:后台传给前端十万条数据,你作为前端如何渲染到页面上? 回答者A:我有句话不知当讲不当讲,这什么鬼需求。 回答者B:滚,后端,我不要这样的数据,你就不能分页给我吗。 回答C:10万条数据这怎么展示,展示了也看不完啊。 分析: 面试官既然能这么问,我们从技术的角度出发,探索一下这道题,上手操作了一下: function loadAll(response) { var html = ""; for (var i = 0; i < 100000; i++) {

Java_cola的博客 1493

在线教育——数据库分表策略

二、数据库分库分表策略 背景 随着业务规模的不断扩大,需要选择合适的方案去应对数据规模的增长,以应对逐渐增长的访问压力和数据量。 数据库的扩展方式主要包括:业务分库、主从复制,数据库分表。 1、业务分库 业务分库指的是按照业务模块将数据分散到不同的数据库服务器。例如,一个简单的电商网站,包括用户、商品、订单三个业务模块,我们可以将用户数据、商品数据、订单数据分开放到三台不同的数据库服务器上,而不是将所有数据都放在一台数据库服务器上。这样的就变成了3个数据库同时承担压力,系统的吞吐量自然就提高了。.

qq_37565377的博客 783

Python操作MongoDB看这一篇就够了

MongoDB是由C++语言编写的非关系型数据库,是一个基于分布式文件存储的开源数据库系统,其内容存储形式类似JSON对象,它的字段值可以包含其他文档、数组及文档数组,非常灵活。在这一节中,我们就来看看Python 3下MongoDB的存储操作。 1. 准备工作 在开始之前,请确保已经安装好了MongoDB并启动了其服务,并且安装好了Python的PyMongo库。 2. 连接MongoDB 连接MongoDB时,我们需要使用PyMongo库里面的MongoClient。一般来说,传入MongoDB的IP及

Java_cola的博客 1477

「论道架构师」优雅解决历史代码中的新需求

事件起因 6月中旬,可爱的产品大大给我提了一个临时需求,需要我对商品创建/更新业务中由开放平台对接而来的请求做一个Check,如果符合要求,则再做一段稍微复杂的逻辑处理。 这种Easy程度的需求怎么拦得住我,不到半天我就Coding,Push一气呵成,正当我准备点一杯喜茶开始摸鱼的时候,我却收到了一封邮件。 邮件里有一堆的汉字和英文,但有几个字赫然在目: 您的代码已被驳回。 当我经历了茫然、震惊、不敢相信、最后无奈接受的情绪转变后,问了评审的同事,为什么要驳回我的代码,他说:“历史代码一般业务都很完整(跟屎

m0_57227221的博客 228

☕【Java原理探索】彻底你明白什么是JIT编译器(Just In Time编译器)

前提概要 我们都知道开发语言整体分为两类,一类是编译型语言,一类是解释型语言。那么你知道二者有何区别吗?编译器和解释器又有什么区别? 这是为了兼顾启动效率和运行效率两个方面。Java程序最初是通过解释器进行解释运行的,当虚拟机返现某个方法或代码块的运行特别频繁时,就会把这段代码标记为热点代码,为了提供热点代码的运行效率,在运行时,虚拟机就会把这些代码编译成与本地平台相关的机器码。并进行各种层次的优化。 编译器和解释器 Java编译器(javac)的作用是将java源程序编译成中间代码字节码文.

Java_cola的博客 1245

springboot 实现拦截器的 3 种方式介绍及异步执行的思考

springboot 拦截器 实际项目中,我们经常需要输出请求参数,响应结果,方法耗时,统一的权限校验等。 本文首先为大家介绍 HTTP 请求中三种常见的拦截实现,并且比较一下其中的差异。 (1)基于 Aspect 的拦截器 (2)基于 HandlerInterceptor 的拦截器 (3)基于 ResponseBodyAdvice 的拦截器 springboot 入门案例 为了便于大家学习,我们首先从最基本的 springboot 例子讲起。 maven 引入 引入必须的 jar 包。 <pare

Java_cola的博客 1187

放弃 Java ,内卷300秒,我 5 点就下班!

今天下班的时候,走在路上,听到前面几个美女在吐槽: “我们公司的程序员 5 点就下班了,工资肯定不高” “程序员还能 5 点就下班啊?真是刷新了我的认知” 不知从什么时候开始,“996”“中年危机”“青春饭”… 这些词好像就成了我们的专属代名词。与此同时,“内卷”也越来越严重了,如果非要给内卷找出一个有代表性的职位的话,那无疑就是Java 工程师。 好巧不巧,我干的就是这个~我无数次问自己,干的活拼的是“智力”还是“体力”。也无数次对自己从事的职业产生怀疑,Java 内卷如此严重,真的有必要坚持下去吗? 我

Java_cola的博客 1807

菜鸟程序员,被无良HR欺骗,因祸得福,竟“意外”拿下【得物】offer

前因后果 先讲述一下自己这次被无良HR欺骗坑惨的经历吧,面试的是一家上海某电商公司,给的薪资是不错。面试的时候,找我要了工资流水,然后给了我口头offer,就让我回去等了邮件了。回去之后就觉得offer没啥问题,稳稳当当了,就没再去面其他的公司,打起了游戏。结果等了两个礼拜也没等来邮件,问HR告诉我在走流程,我问是不是不要我,HR说要,让我继续等。 再过了几天我再去问,HR就怎么都不回我了,这个时候我才反应过来“坏了”。好在后来我马上开始面试其他的公司,阴差阳错拿到了美团的offer,这也算是因祸得福了。

Java_cola的博客 1132

可视化大屏可真是太 beautiful 了

去年4月1日,罗永浩直播带货首秀在抖音进行,这场直播累计观看人数超过3000万人,销售额最终超1.1亿。接着网上发布了对于这场直播数据的“可视化大屏展示”,很多人都好奇这个是用什么做的,今天就带大家做一个类似于下图的可视化大屏。 上图是罗永浩直播数据的可视化大屏展示,下图是本文我们要做的可视化大屏展示,先来给大家看一个视频!如出一辙,有兴趣的可以跟着我操作一遍。 一、ERP系统(企业资源规划) 将资源配比运用到企业身上,叫做“ERP系统”,全称是“EnterPrice Recourse Planning”

Java_cola的博客 796

2021年最常见的Python面试题&答案(上篇)

Python新手在谋求一份Python编程工作前,必须熟知Python的基础知识。编程网站DataFlair的技术团队分享了一份2018年最常见Python面试题合集,既有基本的Python面试题,也有高阶版试题来指导你准备面试,试题均附有答案。面试题内容包括编码、数据结构、脚本撰写等话题。本文为上篇。 Q 1:Python有哪些特点和优点? 作为一门编程入门语言,Python主要有以下特点和优点: 可解释 具有动态特性 面向对象 简明简单 开源 具有强大的社区支持 Q 2:深拷贝和浅拷贝之间的区别是什

Java_cola的博客 1109

全新一代API网关,带可视化管理,文档贼友好!

摘要 提到API网关,大家比较熟悉的有Spring Cloud体系中的Gateway和Zuul,这些网关在使用的时候基本都要修改配置文件或自己开发功能。今天给大家介绍一款功能强大的API网关apisix,自带可视化管理功能,多达三十种插件支持,希望对大家有所帮助! 简介 apisix是一款云原生微服务API网关,可以为API提供终极性能、安全性、开源和可扩展的平台。apisix基于Nginx和etcd实现,与传统API网关相比,apisix具有动态路由和插件热加载,特别适合微服务系统下的API管理。 核.

Java_cola的博客 1067

腾讯云,五轮面试,六个小时,灵魂拷问,含泪拿下 60W offer

在互联网做了几年之后,去大厂“镀镀金”是大部分人的首选。大厂不仅待遇高、福利好,更重要的是,它是对你专业能力的背书,大厂工作背景多少会给你的简历增加几分竞争力。 但说实话,想进大厂还真没那么容易。我的一个朋友在入职腾讯之前,大大小小的面试经历了十几次,最后终于在 4 轮技术面+1 轮 HR 面之后成功接到 Offer,40k*16 薪! 第一轮主要考察 Java 基础 ,比如: hashmap的实现 Java中的垃圾回收 除了代码之外你还学习了什么技术,框架 死锁是怎么产生的 线程和进程的区别 二、三

Java_cola的博客 728

JAVA方法mock调用工具的实现

背景 在生产上线时,可能遇到有一些case不好立即验证; 例如用户必须是xx用户(新用户,流失用户…)才能领到某些活动券,而这样的用户账号不好获取; 例如想让测试用户看到不同的页面效果; 所以希望在调用一些方法接口的时候针对指定入参可以返回指定的返回结果。 这些方法可以是调用上游的dubbo方法,也可以是内部自己的本地方法等。 方案设计 入参出参分析 首先来看方法的参数和返回结果的类型,以及入参和出参组装分类; 入参出参数据类型分类 基本类型或者包装类型:int, double, Integer,St

Java_cola的博客 956

InnoDB 内存结构总览:Change Buffer、AHI 与 Log Buffer

本文系统梳理InnoDB内存结构中的ChangeBuffer、Adaptive Hash Index(AHI)与LogBuffer。ChangeBuffer缓存二级索引页不在内存时的变更,减少随机IO,仅在页加载时合并;聚簇索引修改立即执行,因数据本身不可延后。AHI基于高频等值查询自动构建哈希索引,加速定位,仅支持等值操作。LogBuffer为redo log内存缓冲,配合磁盘日志实现崩溃恢复。三者均服务于性能优化,其中ChangeBuffer与AHI共享BufferPool空间,而LogBuffer独立

bksczm的博客 296

记一次 Feign 的坑

事件回顾 起因 事情是这样的,最近在代码中需要使用 Feign 调用第三方服务。所以就是标准的一套操作: 引入第三方服务 Jar 包。 @EnableFeignClients 注解注入 Bean。 @Autowired 引入 Bean。 然后也没有在意到 Idea 已经有警告了,直接启动服务了。然后就出现如下错误: Description: Field api in com.xxx.service.impl.ServiceImpl required a bean of type

Java_cola的博客 956

【熬夜肝了】HBase设计的实践经验(全)

今天分享的内容是关于HBASE相关设计的实战经验,记录学到的东西。主要是线上(集群规模10~20台,每秒读写数据量在几十万条记录的量级)出现了bug, hbase暂时不提供服务了,即整理了该篇文章。 - 一、[HBASE简介] - 二、[详解HBASE的读和写、读放大、合并、故障恢复等] - 三、[HBASE在告警信息的使用] - 四、 [HBASE的优化经验] HBASE是什么? HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一

Java_cola的博客 876
上一篇: springboot 实现拦截器的 3 种方式介绍及异步执行的思考
下一篇: 菜鸟程序员,被无良HR欺骗,因祸得福,竟“意外”拿下【得物】offer
Python_cola
博客等级 码龄5年 2031粉丝 74原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值