1. 程式人生 > 其它 >springcloudAlibaba-sharding-讀寫分離和分庫分表配置

springcloudAlibaba-sharding-讀寫分離和分庫分表配置

目前市面上很多網際網路公司還是用的mysql資料庫,然而mysql對於高併發(QPS),高訪問量的請求還是比較乏力,就有了各種sql優化

以及快取的應用,提高sql效能和減輕併發量,但是這些還是滿足不了海量使用者請求以及資料sql資料處理。應用而出的ElasticSearch等

搜尋引擎技術,進行資料處理和挖掘,但是這種第三方框架,對資料庫本身的效能還是沒有提升,於是便有了資料庫的分庫,讀寫分離

分表,拆分表或者拆分表結構。

1.分庫-讀寫分離:將增刪改,和查拆分到不同mysql伺服器上,這樣可極大的提高吞吐量,兩個資料庫必須做資料同步,所以讀寫分離是

建立在資料庫叢集或者主從基礎上的,mysql主從配置,我有部落格記錄,這邊就不一一贅述:

https://www.cnblogs.com/pengjr/p/16025390.html

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奇偶數分表。