找回密码
 立即注册
首页 业界区 业界 Go工程选择开源分库分表中间件可用性测试 ...

Go工程选择开源分库分表中间件可用性测试

鄂缮输 前天 21:51
近期在寻找Go工程可以用的开源分库分表中间件,找了3个:ShardingSphere-Proxy,Kingshard,Gaea,下面给出测试过程和对比结果
ShardingSphere-Proxy

https://github.com/apache/shardingsphere
有apache基金会支持,社区活跃, star 20.2k
Kingshard

https://github.com/flike/kingshard
个人项目, github已经不更新了,star 6.4k
Gaea

https://github.com/XiaoMi/Gaea
小米团队发布,最近更新是2024年9月,还算比较新,star 2.7k
分表设置

t_user 分10个表
sharding-proxy是 t_user_0...9
kingshard和Gaea是 t_user_0000...0009
测试代码
  1. package main
  2. import (
  3.         "database/sql"
  4.         "encoding/json"
  5.         "fmt"
  6.         "math/rand"
  7.         "sharding/internal/models"
  8.         "strings"
  9.         _ "github.com/go-sql-driver/mysql" // 导入 MySQL 驱动
  10.         "log"
  11. )
  12. const (
  13.         // 定义颜色的 ANSI 转义序列
  14.         Reset  = "\033[0m"
  15.         Red    = "\033[31m"
  16.         Green  = "\033[32m"
  17.         Yellow = "\033[33m"
  18.         Blue   = "\033[34m"
  19. )
  20. func main() {
  21.         log.Println(Red + "shardingsphere-proxy test" + Reset)
  22.         dsn_proxy := "sharding:sharding@tcp(127.0.0.1:13308)/sharding_user?charset=utf8mb4&parseTime=True&loc=Local"
  23.         sharding_query(dsn_proxy)
  24.         log.Println(Yellow + "kingshard test" + Reset)
  25.         dsn_kingshard := "kingshard:kingshard@tcp(127.0.0.1:9696)/sharding_user?charset=utf8mb4&parseTime=True&loc=Local"
  26.         sharding_query(dsn_kingshard)
  27.         log.Println(Blue + "gaea test" + Reset)
  28.         dsn_gaea := "sharding_gaea:sharding_gaea@tcp(127.0.0.1:13306)/sharding_user?charset=utf8mb4&parseTime=True&loc=Local"
  29.         sharding_query(dsn_gaea)
  30. }
  31. func sharding_query(dsn string) {
  32.         //sharding proxy
  33.         shardingProxyConn, err := sql.Open("mysql", dsn)
  34.         if err != nil {
  35.                 log.Println(err)
  36.                 return
  37.         }
  38.         defer shardingProxyConn.Close()
  39.         id := rand.Intn(10)
  40.         userName := fmt.Sprintf("test%d", id)
  41.         notFound := false
  42.         // 完整sql,无传参
  43.         var uid uint64
  44.         valScope := strings.ReplaceAll(userName, "'", "\\'")
  45.         err = shardingProxyConn.QueryRow(fmt.Sprintf("select id from t_user where login_name = '%s'", valScope)).Scan(&uid)
  46.         if err != nil {
  47.                 if err == sql.ErrNoRows {
  48.                         log.Println("query 1 fail 1: ", err.Error())
  49.                         notFound = true
  50.                 } else {
  51.                         log.Println("query 1 fail 2:", err)
  52.                 }
  53.         } else {
  54.                 log.Println("query 1 success, uid=", uid)
  55.         }
  56.         // sql传参
  57.         err = shardingProxyConn.QueryRow("select id from t_user where login_name = ?", userName).Scan(&uid)
  58.         if err != nil {
  59.                 if err == sql.ErrNoRows {
  60.                         log.Println("query 2 fail 1: ", err.Error())
  61.                         notFound = true
  62.                 } else {
  63.                         log.Println("query 2 fail 2:", err)
  64.                 }
  65.         } else {
  66.                 log.Println("query 2 success, uid=", uid)
  67.         }
  68.         // create
  69.         if notFound {
  70.                 // sharding-proxy 有 id 自动生成配置,这里方便测试需要,指定id
  71.                 sqlIns := "INsert into t_user (id, login_name,passwd,email) values (?, ?, ?, ?)"
  72.                 result, err1 := shardingProxyConn.Exec(sqlIns, id, userName, "test1234", "test@test.com")
  73.                 if err1 != nil {
  74.                         log.Println("insert fail:", err1)
  75.                 } else {
  76.                         rowsAffected, _ := result.RowsAffected()
  77.                         log.Println("insert RowsAffected ", rowsAffected)
  78.                 }
  79.         }
  80.         //Select
  81.         rows, err := shardingProxyConn.Query("select id,login_name,email,create_time,update_time from t_user where login_name like ? limit 10", "%test%")
  82.         if err != nil {
  83.                 log.Println(err)
  84.                 return
  85.         }
  86.         defer rows.Close()
  87.         var userList []models.UserModel
  88.         for rows.Next() {
  89.                 var u models.UserModel
  90.                 e := rows.Scan(&u.ID, &u.LoginName, &u.Email, &u.CreatedTime, &u.UpdateTime)
  91.                 if e != nil {
  92.                         log.Println("row scan err:", e)
  93.                         continue
  94.                 }
  95.                 userList = append(userList, u)
  96.         }
  97.         j, _ := json.Marshal(userList)
  98.         log.Println("select result:", string(j))
  99. }
复制代码
测试结论

shardingsphere-proxy 4.1


  • 分表查询不支持占位符传参,插曲:php测试过支持传参使用
  • 分表只支持全SQL
kingshard


  • 分表查询不支持占位符传参,插曲:php测试过支持传参使用
  • 分表查询支持全SQL
Gaea


  • 分表查询支持占位符传参
  • 分表查询支持全SQL
结论对比

Go代码的工程应用想用分库分表中间件,推荐次序
第1首选优先Gaea,因为支持占位符传参,github最近更新是2024年9月
第2是shardingsphere-proxy 4.1,因为不支持占位符传参,go工程想要用,就全得转换成完整SQL,但是配置比较简单,容易部署,有apache基金会支持,社区活跃
第3是kingshard,因为不支持占位符传参,就全得转换成完整SQL,并且github已经不更新了
测试结果日志
  1. 2025/04/19 17:04:24 shardingsphere-proxy test
  2. 2025/04/19 17:04:25 query 1 success, uid= 1119859588875681792
  3. [mysql] 2025/04/19 17:04:25 packets.go:64 [warn] unexpected seq nr: expected 4, got 5
  4. 2025/04/19 17:04:25 query 2 fail 2: commands out of sync. You can't run this command now
  5. [mysql] 2025/04/19 17:04:25 packets.go:64 [warn] unexpected seq nr: expected 8, got 17
  6. 2025/04/19 17:04:25 select result: null
  7. 2025/04/19 17:04:25 kingshard test
  8. 2025/04/19 17:04:25 query 1 success, uid= 4
  9. 2025/04/19 17:04:25 query 2 fail 2: Error 1105 (HY000): prepare error ERROR 1146 (42S02): Table 'sharding_user.t_user' doesn't exist
  10. 2025/04/19 17:04:25 Error 1105 (HY000): prepare error ERROR 1146 (42S02): Table 'sharding_user.t_user' doesn't exist
  11. 2025/04/19 17:04:25 gaea test
  12. 2025/04/19 17:04:25 query 1 fail 1:  sql: no rows in result set
  13. 2025/04/19 17:04:25 query 2 fail 1:  sql: no rows in result set
  14. 2025/04/19 17:04:25 insert RowsAffected  1
  15. 2025/04/19 17:04:25 select result: [{"created_time":"2025-04-19T00:51:23+08:00","update_time":"2025-04-19T00:51:23+08:00","id":1,"Email":"test@test.com","LoginName":"test1","Passwd":"","LoginStatus":0,"LastLoginTime":null,"LoginCount":0}...]
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册