A flexible read/write splitting component
Current Production Version: 1.0.1
- Component Description This component is designed for one-master, multiple-slave database read/write separation with the following features:
MySQL Replication Support: Works directly with the MySQL replication mechanism by using group datasources to support read/write separation. You can set different weights for each database.
Failover on Fatal Exceptions: If one of the databases goes down (resulting in a defined fatal exception), the component will switch to a read-retry mode to ensure that as many data accesses as possible can be served by the healthy databases.
Thread Protection via Try-Lock Mechanism: Once a fatal exception is caught for the first time, only one thread is allowed to access the database until it returns to normal operation.
Traffic Control & Database Protection: Manages overall access to prevent overload and protect the databases.
Specifying Database Access (ThreadLocal): In a group of equivalent databases (usually only one primary write database with the rest being slaves), there may be master-slave key delays due to replication. For various types of reads (immediate and delayed), you can use GroupDataSourceRouteHelper.executeByGroupDataSourceIndex(int dataSourceIndex) to specify which database should be accessed.
Specifying Database Access (Hint): This is an alternative way to specify which database to access. By placing a comment before the SQL query, you can instruct the TDDL dynamic datasource which database to use. For example:
/+TDDL_GROUP({groupIndex:12})/select * from tab;
- Dependencies You will need to include the following dependencies in your project:
- Component Configuration
DataSource Configuration First, configure both the write (primary) and read (slave) datasources. For example:
20 5 30000 20 5 true 30 true true false select 1 20 1800000 20 5 30000 20 5 true 30 true true false select 1 20 1800000 20 5 30000 20 5 true 30 true true false select 1 20 1800000Injection into the Dynamic DataSource Next, inject the above datasources into the dynamic datasource:
- Configuration Rules Determining DataSource for Reads and Writes The selection of a datasource is based on the priority indicated by the letters p (for read priority) or q (for write priority), which decide whether the datasource is used for read, write, or both. Then, the letters r or w determine the probability (weight) with which the corresponding read or write datasource is selected.
Weight Example For example, given the following configurations:
db1: r10w10p2
db2: r20p2
db3: rp3
The resulting weights would be:
db1: Weight (r10, w10, p2)
db2: Weight (r20, p2)
db3: Weight (rp3)
Here, for read operations, there are two priority groups:
p3: Contains [db3]
p2: Contains [db1, db2]
When performing a read, the datasources in the highest priority group (p3) are attempted first (in this case, db3). If db3 cannot handle the read operation, a datasource is randomly chosen from db1 and db2. Given that db2 has a read weight of 20 versus db1’s 10, db2 has a higher probability of being selected.
Letter Meanings r/R: Indicates that the database can be used for read operations. The subsequent number specifies the read weight; if omitted, it defaults to 10.
w/W: Indicates that the database can be used for write operations. The subsequent number specifies the write weight; if omitted, it defaults to 10.
p/P: Indicates the read operation priority. A higher number means a higher priority. If omitted, the default priority is 0.
q/Q: Indicates the write operation priority. A higher number means a higher priority. If omitted, the default priority is 0.
