springcloudAlibaba-sharding-讀寫分離和分庫分表配置
目前市面上很多網際網路公司還是用的mysql資料庫,然而mysql對於高併發(QPS),高訪問量的請求還是比較乏力,就有了各種sql優化
以及快取的應用,提高sql效能和減輕併發量,但是這些還是滿足不了海量使用者請求以及資料sql資料處理。應用而出的ElasticSearch等
搜尋引擎技術,進行資料處理和挖掘,但是這種第三方框架,對資料庫本身的效能還是沒有提升,於是便有了資料庫的分庫,讀寫分離
分表,拆分表或者拆分表結構。
1.分庫-讀寫分離:將增刪改,和查拆分到不同mysql伺服器上,這樣可極大的提高吞吐量,兩個資料庫必須做資料同步,所以讀寫分離是
建立在資料庫叢集或者主從基礎上的,mysql主從配置,我有部落格記錄,這邊就不一一贅述:
2.分表:分表有垂直分表和水平分表,垂直分表:將欄位進行分割,比如,使用者可以有很作角色,那麼便可以將使用者和角色所需欄位拆分開,
在用中間表關聯,但是對於資料量大的,單表記錄還是會很大。水平分表:水平分表就是將使用者表的資料,分到另外一個有著相同資料結構
的表中,這樣假如有一千萬資料,那麼兩個表相互平分五百萬資料,對於海量資料有著非常明顯的改善與優化。
然後對這些拆分後的庫和表進行增刪改查操作,就需要用到sharding和myCat第三方框架整合進行管理,本次講的就是sharding進行分庫分表
操作,只需要配置即可,不影響正常業務程式碼。直接上乾貨
匯入依賴:
<!--依賴sharding--> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>4.0.0-RC1</version> </dependency> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-core-common</artifactId> <version>4.0.0-RC1</version> </dependency>
yml配置:
spring:
main:
# 需要加入這個,等於true
allow-bean-definition-overriding: true
application:
name: cloud-provider-payment
shardingsphere:
# 引數配置,顯示sql
props:
sql:
show: true
# 配置資料來源
datasource:
# 給每個資料來源取別名,下面的ds1,ds2,ds3任意取名字
names: ds1,ds2
# 給master-ds1每個資料來源配置資料庫連線資訊
ds1:
# 配置druid資料來源
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.0.111:3306/dbc?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
username: root
password: Zhroot@8
maxPoolSize: 100
minPoolSize: 5
# 配置ds2-slave
ds2:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.0.110:3306/dbc?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
username: root
password: Zhroot@8
maxPoolSize: 100
minPoolSize: 5
# 配置資料來源的讀寫分離,但是資料庫一定要做主從複製
masterslave:
# 配置主從名稱,可以任意取名字
name: ms
# 配置主庫master,負責資料的寫入
master-data-source-name: ds1
# 配置從庫slave節點
slave-data-source-names: ds2
# 配置預設資料來源ds1
sharding:
# 預設資料來源,主要用於寫,注意一定要配置讀寫分離 ,注意:如果不配置,那麼就會把三個節點都當做從slave節點,新增,修改和刪除會出錯。
default-data-source-name: ds1
tables:
# 我的表名稱 test_table,進行分表
test_table:
# 分庫節點配置
actual-data-nodes: ds$->{1..2}.test_table_$->{1..2}
# key-generator-column-name: id #主鍵
# key-generator:
# column: id #主鍵
# type: SNOWFLAKE # 指定id進行插入時候,雪花演算法
table-strategy:
inline:
sharding-column: id
#分表節點配置
algorithm-expression: test_table_$->{id % 2 + 1} # 寫法本來是$->{id % 2},但是這種對應於table_0 table_1 我的是1和2 所以需要+1
基礎類:
@Data
@TableName("test_table")
public class TestTableEntity {
private Long id;
private String name;
private String bark;
}
dao層:
@Mapper
public interface TestTableDao{
int create(TestTableEntity entity);
TestTableEntity getTableById(@Param("id") Long id);
}
xml層:
<insert id="create" parameterType="com.pjrspringcloud.entity.TestTableEntity"
useGeneratedKeys="true" keyProperty="id">
insert into test_table(name, bark) value (#{name},#{bark})
</insert>
<select id="getTableById" parameterType="java.lang.Long" resultType="com.pjrspringcloud.entity.TestTableEntity">
select * from test_table where id = #{id}
</select>
service:
public interface TestTableService{
int create(TestTableEntity entity);
TestTableEntity getTableById( Long id);
}
實現類:
@Service
@Log4j2
public class TestTableServiceImpl implements TestTableService {
@Autowired
private TestTableDao tableDao;
@Override
public int create(TestTableEntity entity) {
return tableDao.create(entity);
}
@Override
public TestTableEntity getTableById(Long id) {
return tableDao.getTableById(id);
}
}
controller層:
@RestController
@RequestMapping("testTable")
@Log4j2
public class TestTableController {
@Autowired
private TestTableService tableService;
@PostMapping("create")
public Result create(@RequestParam("name") String name,@RequestParam("bark") String bark) {
TestTableEntity entity = new TestTableEntity();
entity.setName(name);
entity.setBark(bark);
tableService.create(entity);
log.info("插入成功=======name={},bark={}",name,bark);
return new Result().ok("插入成功");
}
@GetMapping("getById")
public Result getById(@RequestParam("id") Long id) {
TestTableEntity entity = tableService.getTableById(id);
log.info("查詢成功============={}",entity);
return new Result().ok(entity);
}
}
啟動後進行介面業務測試,成功!
注意:水平分表必須選擇一種分表策略,也可以自定義分表策略,我這裡展示的是id奇偶數分表。