Sharding-jdbc中的很多地方涉及到算法,比如主从配置这块、分库分表这块。本文主要从源码角度介绍下,目前主要包含哪些算法,以及这些算法的内容。

一、读写分离(主从配置)

这块的代码主要在core模块中的api/algorithm/masterslave下面,这块的算法的主要目的,其实是在读的时候,如何选择从数据库。按照常规的理解,可以有以下几种(参考dubbo):

  • 随机算法
  • 轮询
  • 最小活跃
  • 一致性hash

目前在sharding-jdbc中,实现了前两种,我们看下是如何实现的。

首先是一个接口,定义了获取slave的方法,即:

public interface MasterSlaveLoadBalanceAlgorithm {

    /**
* Get data source.
*
* @param name master-slave logic data source name
* @param masterDataSourceName name of master data sources
* @param slaveDataSourceNames names of slave data sources
* @return name of selected data source
*/
String getDataSource(String name, String masterDataSourceName, List<String> slaveDataSourceNames);
}

最终需要返回的是slave的名称,后续根据这个名称可以获取到连接池。

下面我们看下两种实现:

  • RandomMasterSlaveLoadBalanceAlgorithm
public String getDataSource(final String name, final String masterDataSourceName, final List<String> slaveDataSourceNames) {
return slaveDataSourceNames.get(new Random().nextInt(slaveDataSourceNames.size()));
}

可以看到,随机了一个slave集群大小的随机数,然后从slave list中获取对应的slave name。

  • RoundRobinMasterSlaveLoadBalanceAlgorithm
private static final ConcurrentHashMap<String, AtomicInteger> COUNT_MAP = new ConcurrentHashMap<>();

@Override
public String getDataSource(final String name, final String masterDataSourceName, final List<String> slaveDataSourceNames) {
AtomicInteger count = COUNT_MAP.containsKey(name) ? COUNT_MAP.get(name) : new AtomicInteger(0);
COUNT_MAP.putIfAbsent(name, count);
count.compareAndSet(slaveDataSourceNames.size(), 0);
return slaveDataSourceNames.get(count.getAndIncrement() % slaveDataSourceNames.size());
}

这块用了一个缓存,COUNT_MAP,缓存的内容是name-count的键值对,而count是一个原子类,它的值一直是0,1,...,slaves.size()-1,0,1..这样循环,所以每个slave都会被轮询到。

二、分库分表

分库分表的算法目前支持的内容包括:

  • 精确分库分表PreciseShardingValue
  • 按照范围分库分表RangeShardingValue
  • 按照列表分库分表ListShardingValue

这块主要是定义了一些接口,具体的实现还是要看自己来实现。我们来看下example中的一些已经实现的算法。

public final class PreciseModuloDatabaseShardingAlgorithm implements PreciseShardingAlgorithm<Integer> {

    @Override
public String doSharding(final Collection<String> availableTargetNames, final PreciseShardingValue<Integer> shardingValue) {
for (String each : availableTargetNames) {
if (each.endsWith(shardingValue.getValue() % 2 + "")) {
return each;
}
}
throw new UnsupportedOperationException();
}
}

这块就是实现了一个精准分片的算法,我们主要看下doSharding这个方法,里面包含两个参数availableTargetNames和shardingValue。那么这两个是什么呢?我们debug一下,跟踪一下代码,可以看到,shardingValue其实就是分片项,也就是比如order_id、user_id等等字段值,而availableTargetNames就是所谓的实际数据库表节点。这边遍历的也是实际节点,当分片项(或分片字段)满足一定的条件时,返回实际数据库表节点,用于组装sql。

总的来说,分片算法这块其实根据自己的业务需求自己进行扩展的,总的来说还是要根据实际的机器部署情况来。另外读写分离这块是否需要进行扩展,也是看后续的需要。

【源码解析】Sharding-Jdbc中的算法的更多相关文章

  1. Spring5源码解析-Spring框架中的单例和原型bean

    Spring5源码解析-Spring框架中的单例和原型bean 最近一直有问我单例和原型bean的一些原理性问题,这里就开一篇来说说的 通过Spring中的依赖注入极大方便了我们的开发.在xml通过& ...

  2. Mybatis源码解析1—— JDBC

    在之前的文章中,我为大家介绍了 Mybatis 的详细用法,算是基础教程. 详细链接:Mybatis 基础教程 言归正传,只懂基础可不行,接下来将给大家带来高阶的源码解析教程,从浅入深,通过源码解析, ...

  3. 从源码解析 Spring JDBC 异常抽象

    初入学习 JDBC 操作数据库,想必大家都写过下面的代码: 数据库为:H2 如果需要处理特定 SQL 异常,比如 SQL 语句错误,这个时候我们应该怎么办? 查看 SQLException 源码,我们 ...

  4. Redis源码解析:13Redis中的事件驱动机制

    Redis中,处理网络IO时,采用的是事件驱动机制.但它没有使用libevent或者libev这样的库,而是自己实现了一个非常简单明了的事件驱动库ae_event,主要代码仅仅400行左右. 没有选择 ...

  5. html 网页源码解析:bs4中BeautifulSoup

    from bs4 import BeautifulSoup result=requests.request("get","http://www.baidu.com&quo ...

  6. ReactiveCocoa源码解析(四) Signal中的静态属性静态方法以及面向协议扩展

    上篇博客我们聊了Signal的几种状态.Signal与Observer的关联方式以及Signal是如何向关联的Observer发送事件的.本篇博客继续上篇博客的内容,来聊一下Signal类中静态的ne ...

  7. ReactiveSwift源码解析(四) Signal中的静态属性静态方法以及面向协议扩展

    上篇博客我们聊了Signal的几种状态.Signal与Observer的关联方式以及Signal是如何向关联的Observer发送事件的.本篇博客继续上篇博客的内容,来聊一下Signal类中静态的ne ...

  8. 【Mybatis源码解析】- JDBC连接数据库的原理和操作

    JDBC连接数据库的原理和操作 JDBC即Java DataBase Connectivity,java数据库连接:JDBC 提供的API可以让JAVA通过API方式访问关系型数据库,执行SQL语句, ...

  9. Syncthing源码解析 - 在Gogland中对Syncthing的各个模块进行调试?

    Syncthing的模块很多,各自负责不同的功能,如何能够对各个模块进行调试?Syncthing开发者早就想到这个问题了,允许开发者对任意模块进行单独调试,也允许同时对所有模块调试,调试方式是打印各个 ...

随机推荐

  1. 标准输入输出 stdio 流缓冲

    **From : http://www.pixelbeat.org/programming/stdio_buffering/** 我发现找出标准流用的是什么缓冲是一件困难的事. 例如下面这个使用uni ...

  2. ActiveMQ——activemq的详细说明,queue、topic的区别(精选)

    JMS中定义了两种消息模型:点对点(point to point, queue)和发布/订阅(publish/subscribe,topic).主要区别就是是否能重复消费. 点对点:Queue,不可重 ...

  3. Chloe.ORM框架应用实践

    Chloe.ORM 是国人开发的一款数据库访问组件,很是简单易用.目前支持四种主流数据库:SqlServer.MySQL.Oracle,以及Sqlite,作者为这四种数据库划分出了各自对应的组件程序集 ...

  4. uva10003 - Cutting Sticks(简单动规)

    /* * Author: Bingo * Created Time: 2015/2/13 18:33:03 * File Name: uva10003.cpp */ #include <iost ...

  5. C setjmp和longjmp

    #include <stdio.h> #include <setjmp.h> void test(jmp_buf *env) { printf("setjmp tes ...

  6. LINUX 笔记-iostat命令

    显示CPU和I/O统计信息 iostat的不带参数的显示CPU和I/ O的所有分区的统计信息 -c Display the CPU utilization report. -d Display the ...

  7. Hadoop(十四)MapReduce原理分析

    前言 上一篇我们分析了一个MapReduce在执行中的一些细节问题,这一篇分享的是MapReduce并行处理的基本过程和原理. Mapreduce是一个分布式运算程序的编程框架,是用户开发“基于had ...

  8. Windows下Mysql5.7开启binlog步骤及注意事项

    1.查看是否开启了binlog:show binary logs; 默认情况下是不开启的. 2.开启binlog:修改mysql的配置文件my.ini.添加如下配置: 该文件默认不允许修改,需要右键“ ...

  9. 《Web前端开发修炼之道》-读书笔记CSS部分

    如何组织CSS-分层 应用 css 的能力分两部分:一部分是css的API,重点是如何用css控制页面内元素的样式:另一部分是css框架,重点是如何对 css 进行组织.如何组织 css 可以有多种角 ...

  10. continous integration environment (Jenkins and bitbucket configuration)

    ================================================================================ continous integrati ...