长文多图:一文讲清楚应对单数据表海量数据的六种策略( 三 )


我们可以使用分布式锁加上自旋解决这个问题 , 本文给出一段示例代码 , 具体原理请参看我之前的一篇文章:缓存穿透与击穿问题解决方案
/*** 业务回调** @author 微信公众号「JAVA前线」**/public interface RedisBizCall {/*** 业务回调方法** @return 序列化后数据值*/String call();}/*** 安全缓存管理器** @author 微信公众号「JAVA前线」**/@Servicepublic class SafeRedisManager {@Resourceprivate RedisClient RedisClient;@Resourceprivate RedisLockManager redisLockManager;public String getDataSafe(String key, int lockExpireSeconds, int dataExpireSeconds, RedisBizCall bizCall, boolean alwaysRetry) {boolean getLockSuccess = false;try {while(true) {String value = https://www.520longzhigu.com/shenghuo/redisClient.get(key);if (StringUtils.isNotEmpty(value)) {return value;}/** 竞争分布式锁 **/if (getLockSuccess = redisLockManager.tryLock(key, lockExpireSeconds)) {value = redisClient.get(key);if (StringUtils.isNotEmpty(value)) {return value;}/** 查询数据库 **/value = bizCall.call();/** 数据库无数据则返回**/if (StringUtils.isEmpty(value)) {return null;}/** 数据存入缓存 **/redisClient.setex(key, dataExpireSeconds, value);return value;} else {if (!alwaysRetry) {logger.warn("竞争分布式锁失败,key={}", key);return null;}Thread.sleep(100L);logger.warn("尝试重新获取数据,key={}", key);}}} catch (Exception ex) {logger.error("getDistributeSafeError", ex);return null;} finally {if (getLockSuccess) {redisLockManager.unLock(key);}}}}


4 分我们首先看一个概念:读写比 。互联网场景中一般是读多写少 , 例如浏览20次订单列表信息才会进行1次确认收货 , 此时读写比例就是20:1 。面对读多写少这种情况我们可以做什么呢?
我们可以部署多台MySQL读库专门用来接收读请求 , 主库接收写请求并通过binlog实时同步的方式将数据同步至读库 。MySQL官方即提供这种能力 , 进行简单配置即可 。




那么客户端怎么知道访问读库还是写库呢?推荐使用ShardingSphere组件 , 通过配置将读写请求分别路由至读库或者写库 。


5 拆如果删除了历史数据并采用了其它存储介质 , 也用了读写分离 , 但是单表压力还是太大怎么办?这时我们只能拆分数据表 , 即把单库单表数据迁移到多库多张表中 。
假设有一个电商数据库存放订单、商品、支付三张业务表 。随着业务量越来越大 , 这三张业务数据表也越来越大 , 我们就以这个例子进行分析 。


5.1 垂直拆分垂直拆分就是按照业务拆分 , 我们将电商数据库拆分成三个库 , 订单库、商品库 。支付库 , 订单表在订单库 , 商品表在商品库 , 支付表在支付库 。这样每个库只需要存储本业务数据 , 物理隔离不会互相影响 。


5.2 水平拆分按照垂直拆分方案 , 现在我们已经有三个库了 , 平稳运行了一段时间 。但是随着业务增长 , 每个单库单表的数据量也越来越大 , 逐渐到达瓶颈 。
这时我们就要对数据表进行水平拆分 , 所谓水平拆分就是根据某种规则将单库单表数据分散到多库多表 , 从而减小单库单表的压力 。
水平拆分策略有很多方案 , 最重要的一点是选好ShardingKey , 也就是按照哪一列进行拆分 , 怎么分取决于我们访问数据的方式 。


5.2.1 范围分片现在我们要对订单库进行水平拆分 , 我们选择的ShardingKey是订单创建时间 , 拆分策略如下:
(1) 拆分为四个数据库 , 分别存储每个季度的数据(2) 每个库三张表 , 分别存储每个月的数据


以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!

「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助: