All Projects → chenjy16 → Xudanrw

chenjy16 / Xudanrw

一个灵活的读写分离组件

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Xudanrw

Unrealm
Unrealm is an extension on RealmCocoa, which enables Swift native types to be saved in Realm.
Stars: ✭ 425 (+4622.22%)
Mutual labels:  db
Jsqdatasourceskit
⚠️ Deprecated ⚠️
Stars: ✭ 692 (+7588.89%)
Mutual labels:  datasource
Db Mysql
Stars: ✭ 22 (+144.44%)
Mutual labels:  db
Jvedio
Windows desktop application to manage local video;Support baidu AI, youdao translation;Support FFMPEG video processing;Support multi-database management and statistics;Support skin switching
Stars: ✭ 545 (+5955.56%)
Mutual labels:  db
Node Sqlite
SQLite client for Node.js applications with SQL-based migrations API written in Typescript
Stars: ✭ 642 (+7033.33%)
Mutual labels:  db
Ip Database
🇨🇳免费IP地址数据库(纯真IP,QQwry,输出格式为国家、省、市、县、运营商),中文数据库,方便实用。
Stars: ✭ 736 (+8077.78%)
Mutual labels:  db
Tendermint
⟁ Tendermint Core (BFT Consensus) in Go
Stars: ✭ 4,491 (+49800%)
Mutual labels:  db
Modelassistant
Elegant library to manage the interactions between view and model in Swift
Stars: ✭ 26 (+188.89%)
Mutual labels:  datasource
Bitcask
🔑A high performance Key/Value store written in Go with a predictable read/write performance and high throughput. Uses a Bitcask on-disk layout (LSM+WAL) similar to Riak.
Stars: ✭ 654 (+7166.67%)
Mutual labels:  db
Orbit Db Http Api
A HTTP API Server for the OrbitDB distributed peer-to-peer database
Stars: ✭ 17 (+88.89%)
Mutual labels:  db
Datasources
💾 🔜📱 Type-safe data-driven CollectionView, TableView Framework. (We can also use ASCollectionNode)
Stars: ✭ 553 (+6044.44%)
Mutual labels:  datasource
Diffabledatasources
💾 A library for backporting UITableView/UICollectionViewDiffableDataSource.
Stars: ✭ 601 (+6577.78%)
Mutual labels:  datasource
Drive Db
📊 Use Google Drive spreadsheets as a simple database
Stars: ✭ 782 (+8588.89%)
Mutual labels:  db
Qb
The database toolkit for go
Stars: ✭ 524 (+5722.22%)
Mutual labels:  db
Rxdatasources Texture
ASTable and ASCollection Data Sources for RxSwift (Texture)
Stars: ✭ 25 (+177.78%)
Mutual labels:  datasource
Dttableviewmanager
Protocol-oriented UITableView management, powered by generics and associated types.
Stars: ✭ 424 (+4611.11%)
Mutual labels:  datasource
Hasor
Hasor是一套基于 Java 语言的开发框架,区别于其它框架的是 Hasor 有着自己一套完整的体系,同时还可以和先有技术体系做到完美融合。它包含:IoC/Aop容器框架、Web框架、Jdbc框架、RSF分布式RPC框架、DataQL引擎,等几块。
Stars: ✭ 713 (+7822.22%)
Mutual labels:  db
Node Pg Migrate
Node.js database migration management for Postgresql
Stars: ✭ 838 (+9211.11%)
Mutual labels:  db
Thinningcoordinator
The UITableView/UICollectionView dataSource/delegate thinning coordinator, help thinning your UIViewController!
Stars: ✭ 25 (+177.78%)
Mutual labels:  datasource
Imdbpy
IMDbPY is a Python package useful to retrieve and manage the data of the IMDb movie database about movies, people, characters and companies
Stars: ✭ 792 (+8700%)
Mutual labels:  db

xudanrw

一个灵活的读写分离组件

目前生产环境版本:1.0.1

Image text

1、组件说明:

本组件适用于一主多从数据库读写分离,功能如下:

1)针对mysql replication机制进行的数据主备复制,可以直接使用group datasource来支持读写分离。读写分离支持权重设置,允许对不同库使用不同的权重;

2)一台数据库挂掉后,如果是个fatal exception(有定义),那么会进入读重试,以确保尽可能多的数据访问可以在正常数据库中访问;

3)使用try – lock机制来进行线程保护,在第一次捕捉到fatal exception以后,只允许一个线程进入数据库进行数据访问,直到数据库可以正常的工作为止;

4)流量控制,数据库保护;

5) 指定数据库访问(ThreadLocal),一组对等数据库中,写库一般只配置一个,其余数据库都为备库,因为通过复制机制,所以主备主键有延迟,对于各种类型的读(实时读和延迟读),

 可以使用GroupDataSourceRouteHelper.executeByGroupDataSourceIndex(int dataSourceIndex)指定需要访问的数据库;

6)指定数据库访问(Hint),这是指定数据库访问的另外一种方式. 这种方式是在sql之前加注释,告知tddl动态数据源该选择第几个数据库.类似:/*+TDDL_GROUP({groupIndex:12})*/select * from tab  ;

2、依赖组件:

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<spring.version>4.3.7.RELEASE</spring.version>
    <dependency>

        <groupId>org.springframework</groupId>

        <artifactId>spring-context-support</artifactId>

        <version>${spring.version}</version>

    </dependency>

    <dependency>

        <groupId>org.springframework</groupId>

        <artifactId>spring-aop</artifactId>

        <version>${spring.version}</version>

    </dependency>

    <dependency>

        <groupId>org.springframework</groupId>

        <artifactId>spring-tx</artifactId>

        <version>${spring.version}</version>

    </dependency>

    <dependency>

        <groupId>org.springframework</groupId>

        <artifactId>spring-jdbc</artifactId>

        <version>${spring.version}</version>

    </dependency>

    <dependency>

        <groupId>org.aspectj</groupId>

        <artifactId>aspectjweaver</artifactId>

        <version>1.7.2</version>

    </dependency>

    <dependency>

        <groupId>org.slf4j</groupId>

        <artifactId>slf4j-api</artifactId>

        <version>1.7.6</version>

    </dependency>

   <dependency>

        <groupId>ch.qos.logback</groupId>

        <artifactId>logback-classic</artifactId>

        <version>1.1.2</version>

    </dependency>

3、组件配置:

首先配置好写库和读库的数据源:

           <bean id="writeDataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
                <property name="driverClassName" value="${database.core.write.driverClassName}" />
                <property name="url" value="${database.core.write.url}" />
                <property name="username" value="${database.core.write.username}" />
                <property name="password" value="${database.core.write.password}" />
                <property name="maxActive"><value>20</value></property>   
                <property name="initialSize"><value>5</value></property>   
                <property name="maxWait"><value>30000</value></property>        <!-- 超时等待时间  以毫秒为单位 -->
                <property name="maxIdle"><value>20</value></property>            <!-- 最大空闲连接 -->
                <property name="minIdle"><value>5</value></property>             <!-- 最小空闲连接 -->
                <property name="removeAbandoned"><value>true</value></property>  <!-- 是否自动回收超时连接 -->
                <property name="removeAbandonedTimeout"><value>30</value></property>  <!-- 超时时间(以秒数为单位) -->
                <property name="testWhileIdle"><value>true</value></property>    <!-- 打开检查,用异步线程evict进行检查 -->   
                <property name="testOnBorrow"><value>true</value></property>   
                <property name="testOnReturn"><value>false</value></property>   
                <property name="validationQuery"><value>select 1</value></property>          
                <property name="numTestsPerEvictionRun"><value>20</value></property>  
                <property name="minEvictableIdleTimeMillis"><value>1800000</value></property>        
            </bean>


      
         <bean id="readDataSource1" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
          <property name="driverClassName" value="${database.core.read1.driverClassName}" />
          <property name="url" value="${database.core.read1.url}" />
          <property name="username" value="${database.core.read1.username}" />
          <property name="password" value="${database.core.read1.password}" />
          <property name="maxActive"><value>20</value></property>   
          <property name="initialSize"><value>5</value></property>   
          <property name="maxWait"><value>30000</value></property>        <!-- 超时等待时间  以毫秒为单位 -->
          <property name="maxIdle"><value>20</value></property>            <!-- 最大空闲连接 -->
          <property name="minIdle"><value>5</value></property>             <!-- 最小空闲连接 -->
          <property name="removeAbandoned"><value>true</value></property>  <!-- 是否自动回收超时连接 -->
          <property name="removeAbandonedTimeout"><value>30</value></property>  <!-- 超时时间(以秒数为单位) -->
          <property name="testWhileIdle"><value>true</value></property>    <!-- 打开检查,用异步线程evict进行检查 -->   
          <property name="testOnBorrow"><value>true</value></property>   
          <property name="testOnReturn"><value>false</value></property>   
          <property name="validationQuery"><value>select 1</value></property>          
          <property name="numTestsPerEvictionRun"><value>20</value></property>  
          <property name="minEvictableIdleTimeMillis"><value>1800000</value></property>        
      </bean>


            <bean id="readDataSource2" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
             <property name="driverClassName" value="${database.core.read2.driverClassName}" />
             <property name="url" value="${database.core.read2.url}" />
             <property name="username" value="${database.core.read2.username}" />
             <property name="password" value="${database.core.read2.password}" />
             <property name="maxActive"><value>20</value></property>   
             <property name="initialSize"><value>5</value></property>   
             <property name="maxWait"><value>30000</value></property>        <!-- 超时等待时间  以毫秒为单位 -->
             <property name="maxIdle"><value>20</value></property>            <!-- 最大空闲连接 -->
             <property name="minIdle"><value>5</value></property>             <!-- 最小空闲连接 -->
             <property name="removeAbandoned"><value>true</value></property>  <!-- 是否自动回收超时连接 -->
             <property name="removeAbandonedTimeout"><value>30</value></property>  <!-- 超时时间(以秒数为单位) -->
             <property name="testWhileIdle"><value>true</value></property>    <!-- 打开检查,用异步线程evict进行检查 -->   
             <property name="testOnBorrow"><value>true</value></property>   
             <property name="testOnReturn"><value>false</value></property>   
             <property name="validationQuery"><value>select 1</value></property>          
             <property name="numTestsPerEvictionRun"><value>20</value></property>  
             <property name="minEvictableIdleTimeMillis"><value>1800000</value></property>        
         </bean>

然后将这些数据源注入动态数据源:

         <!-- 读写分离配置 -->
         <bean id="dsconfDO" class="com.midea.trade.rws.util.DsConfDO">
              <property name="writeRestrictTimes" value="0"/><!-- 时间范围内写限制次数 -->
              <property name="readRestrictTimes" value="0"/><!-- 时间范围内读限制次数 -->
              <property name="timeSliceInMillis" value="0"/><!-- 时间范围不能小于1000ms -->
              <property name="maxConcurrentReadRestrict" value="0"/><!-- 最大并发读限制 -->
              <property name="maxConcurrentWriteRestrict" value="0"/><!-- 最大并发写限制 -->
          </bean>  
             <bean id="fetcher" class="com.midea.trade.rws.util.SpringDataSourceFetcher"/>
             <bean id="groupDataSource" class="com.midea.trade.rws.group.TGroupDataSource">
              <constructor-arg name="dsKeyAndWeightCommaArray" value="writeDataSource:wq1,readDataSource1:rp3,readDataSource2:rp3"/>  
              <constructor-arg ref="fetcher"/>
              <constructor-arg ref="dsconfDO"/>
         </bean>

配置的规则如下:

     首先根据p或q的优先级来决定是读库还是写库还是读写都有,然后根据r或w决定读库或写库被选中的概率。
  
     例子如下:
  
     如:db1: r10w10p2, db2: r20p2, db3: rp3,则对应如下三个Weight:
  
     db1: Weight(r10w10p2)
  
     db2: Weight(r20p2)
  
      db3: Weight(rp3)
  
       在这个例子中,对db1, db2,db3这三个数据库的读操作分成了两个优先级:
  
      p3->[db3]
  
     p2->[db1, db2]
  
     当进行读操作时,因为db3的优先级最高,所以优先从db3读,

 如果db3无法进行读操作,再从db1, db2中随机选一个,因为db2的读权重是20,而db1是10,所以db2被选中的机率比db1更大。




      注:字母r或R表示可以对数据库进行读操作, 后面跟一个数字表示读操作的权重,如果字母r或R后面没有数字,则默认是10;

       字母w或W表示可以对数据库进行写操作, 后面跟一个数字表示写操作的权重,如果字母w或W后面没有数字,则默认是10;

      字母p或P表示读操作的优先级, 数字越大优先级越高,读操作优先从优先级最高的数据库中读数据,如果字母p或P后面没有数字,则默认优先级是0;

      字母q或Q表示写操作的优先级, 数字越大优先级越高,写操作优先从优先级最高的数据库中写数据,如果字母q或Q后面没有数字,则默认优先级是0.

      字母i或I表示动态DBIndex, 和用户通过threadLocal指定的dbIndex结合,实现rw之上更灵活的路由 一个db可以同时配置多个i;不同的db可以配置相同的i,

      例如 db0:i0i2,db1:i1,db2:i1,db3:i2则用户指定dbIndex=0,路由到db0;(只有db0有i0) 用户指定dbIndex=1,随机路由到db1和db2;(db1和db2都有i1)
      用户指定dbIndex=2,随机路由到db0和db3;(db0和db3都有i2)

读写分离交流群:303216689

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].