ShardingSphere 指南
1. 概述
Apache ShardingSphere是一個開源項目,由一組用於數據處理的集成工具組成。它提供了一組功能,例如分佈式數據庫解決方案、事務、治理等。
在本教程中,我們將提供此生態系統的快速概述和入門指南。
2.什麼是ShardingSphere?
Apache ShardingSphere 最初稱為 Sharding-JDBC,旨在解決 Java 應用程序的數據分片問題。然而,現在它已經擴展到一套工具,包括代理、sidecar,以及處理除分片之外的其他功能。
在考慮使用ShardingSphere時,重要的是要知道這樣的項目會給我們的解決方案帶來什麼樣的優勢。我們可以做到以下幾點:
- 性能:考慮到項目的成熟度,該驅動程序在效率和性能方面接近原生 JDBC
- 兼容性:驅動程序可以連接任何實現JDBC規範的數據庫;除此之外,任何使用 MySQL 和 PostgreSQL 的應用程序使用的代理
- 零業務入侵:故障轉移不會影響業務
- 低運營和維護成本:快速學習曲線,並且對當前堆棧的干預最少
- 安全性和穩定性:在確保兩者的同時添加額外的功能
- 彈性擴展:僅擴展
- 開放的生態系統:提供出色的靈活性
3. 使用案例
現在,讓我們進一步了解這些功能,並簡要描述 ShardingSphere 上下文中的每個用例。
3.1.分片
分片是將數據庫分割成更小的部分(稱為分片)並分佈在多個服務器上的做法。 ShardingSphere 簡化了這一過程,使開發人員能夠更有效地分發數據,從而提高應用程序的性能和可擴展性。
3.2.分佈式事務
事務可能需要更改分佈式系統中多個數據庫上的數據。 ShardingSphere 提供了一種管理這些分佈式事務的機制,確保所有涉及的數據庫之間的數據一致性。
3.3.讀/寫分離
這是一種通過將讀寫操作定向到不同的數據庫來優化數據庫訪問的方法。 ShardingSphere可以自動將讀操作路由到副本數據庫,將寫操作路由到主數據庫,從而平衡負載並提高系統的整體性能。
3.4.數據庫網關
ShardingSphere作為數據庫網關,將多個數據庫的複雜性抽象為應用程序的統一數據接口。這使得開發人員可以像單個實體一樣與各種數據庫進行交互,從而簡化了數據庫管理。
3.5.交通治理
ShardingSphere可以對系統中的數據流量進行細粒度的控制。它提供數據分片、讀寫分離等功能,可以有效地在各種資源之間分配流量負載。
3.6.數據遷移
ShardingSphere提供對分片或數據庫之間數據遷移的支持。通過添加或刪除數據庫節點來擴展系統時,它有助於順利地重新分配數據。
3.7.加密
ShardingSphere支持數據在保存到數據庫之前自動加密,提供額外的安全保障。這在處理敏感數據(例如用戶密碼或個人身份信息)時特別有用。
3.8.數據脫敏
數據屏蔽是用修改後的內容(字符或其他數據)隱藏原始數據的過程。 ShardingSphere支持數據脫敏,這在非生產環境中對於確保數據隱私至關重要。
3.9.陰影
ShardingSphere中的Shadow功能可以讓您在不影響實際生產環境的情況下測試數據庫更新、新SQL語句和索引的影響。這是通過將某些流量路由到與實際數據庫並行的影子數據庫來完成的。
3.10.可觀測性
ShardingSphere 提供了一種監控分片數據庫的運行狀況和性能的機制。它支持查詢跟踪、延遲跟踪、流量洞察等指標,使開發人員能夠實時觀察和診斷問題。
4. 入門
為了介紹此類技術並開始習慣它,讓我們以使用 Maven 的 Spring Boot 應用程序為例。
如前所述,該項目中有多種可用功能。因此,為了簡單起見,我們現在僅使用分片功能。這樣做可以讓我們知道如何配置解決方案並將其集成到我們的示例應用程序中。
4.1.依賴關係
第一步是將最新的項目依賴項添加到我們的pom.xml
中:
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core</artifactId>
<version>5.4.0</version>
</dependency>
這使我們能夠開始配置數據源以使用 ShardingSphere。
4.2.數據源配置
現在我們已經有了所需的依賴項,我們必須配置數據源以使用 ShardingSphere JDBC 驅動程序。這裡我們必須定義我們想要使用的功能,在本例中是分片功能。
我們的Order
表的數據將根據order_id
字段的 mod 分佈在兩個 MySQL 實例上。為此,我們將創建一個sharding.yml
文件來保存必要的配置並將其放置在我們的資源文件夾下:
dataSources:
ds0:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.jdbc.Driver
jdbcUrl: jdbc:mysql://localhost:13306/ds0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
username: test
password: test
ds1:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.jdbc.Driver
jdbcUrl: jdbc:mysql://localhost:13307/ds1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
username: test
password: test
rules:
- !SHARDING
tables:
order:
actualDataNodes: ds${0..1}.order
defaultDatabaseStrategy:
standard:
shardingColumn: order_id
shardingAlgorithmName: database_inline
defaultTableStrategy:
none:
shardingAlgorithms:
database_inline:
type: INLINE
props:
algorithm-expression: ds${order_id % 2}
props:
sql-show: false
接下來,我們需要配置 JPA 以使用這些設置。
4.3. JPA配置
現在,我們需要將 JPA/Spring Data 設置連接到 ShardingSphere 數據源。現在讓我們調整application.yml
以使用剛才提到的配置:
spring:
datasource:
driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
url: jdbc:shardingsphere:classpath:sharding.yml
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
...
對於其餘的,我們的應用程序應該通過定義我們的實體和存儲庫來遵循默認的 Spring Data JPA 模式。例如,在我們的例子中,我們可以考慮以下類:
@Entity
@Table(name = "`order`")
public class Order {
@Id
@Column(name = "order_id")
private Long orderId;
@Column(name = "customer_id")
private Long customerId;
@Column(name = "total_price")
private BigDecimal totalPrice;
@Enumerated(EnumType.STRING)
@Column(name = "order_status")
private Status orderStatus;
@Column(name = "order_date")
private LocalDate orderDate;
@Column(name = "delivery_address")
private String deliveryAddress;
// ... getter and setters
}
這是我們的Order
類的映射,接下來我們還可以看到它各自的存儲庫:
public interface OrderRepository extends JpaRepository<Order, Long> { }
正如我們所觀察到的,標準 Spring JPA。此時無需更改其他代碼。
5. 連接點
通過最小的更改,ShardingSphere 使我們能夠將分片策略應用於我們的表。但是,應用程序不需要進行重大更改。實際上,只需要更改持久層的配置。
由於ShardingSphere與JDBC驅動程序的完美集成,我們的應用程序幾乎無需更改代碼即可利用高級功能。
六,結論
在本文中,我們給出了使用 ShardingSphere 的第一步。 ShardingSphere 是一個用於管理和操作分佈式系統中的數據庫的強大工具,它提供了大量的高級功能,但抽象了很多複雜性。
與往常一樣,本文中使用的所有代碼示例都可以在 GitHub 上獲取。