Readyset 是 MySQL 轻量级缓存解决方案

2024-08-19 16:10:44 浏览数 (1)

简介

Readyset 是一种轻量级缓存解决方案,利用内存来存储缓存数据,实现复杂的 SQL 闪电般快速查询。

Readyset 介于应用程序和数据库之间,是一个 Cache 层。相当于 Redis/Memcached 的作用,但它不需要更改你的一行代码。

架构

Java/PHP应用程序 -> Readyset -> MySQL数据库

Readyset 缓存架构示意图Readyset 缓存架构示意图

Readyset 的工作流程如下:

1.对于读操作:

  • 您直接向 Readyset 发送 SQL 查询。
  • 如果结果已缓存,Readyset 会即时返回,实现亚毫秒级响应。
  • 若未缓存,Readyset 会将请求转发至后端数据库,获取结果后缓存并返回。

2.对于写操作(INSERT、UPDATE、DELETE):

  • Readyset 会直接将请求转发至后端数据库执行,并相应更新其缓存。

Readyset 的优势在于:

  • 使用标准 SQL 即可访问,无需学习新的查询语言
  • 无需修改应用程序代码,只需更改数据库连接字符串
  • 支持复杂 SQL 查询的高速缓存
  • 自动保持缓存与数据库的一致性
  • 可选择性地缓存高频查询,优化资源利用

这种设计使 Readyset 特别适合读密集型应用,能显著提升查询性能,同时保持操作的简便性和数据的最终一致性。

安装与使用

1.下载Readyset Docker 镜像

代码语言:bash复制
shell> docker pull readysettech/readyset

2.运行 Readyset 服务

代码语言:bash复制
shell> docker run -d -p 3307:3307 -p 6034:6034                      
--name readyset                                                     
-e UPSTREAM_DB_URL=mysql://admin:123456@192.168.137.131:6666/test   
-e LISTEN_ADDRESS=0.0.0.0:3307                                      
readysettech/readyset:latest                                        

注:UPSTREAM_DB_URL参数值填写后端MySQL的用户名,密码,IP地址,端口号,数据库名。

代码语言:bash复制
# docker ps -a
CONTAINER ID   IMAGE                          COMMAND                   CREATED       STATUS   
    PORTS                                                                                  NAMESf97818f52261   readysettech/readyset:latest   "/usr/local/bin/read…"   6 hours ago   Up 6 hours
   0.0.0.0:3307->3307/tcp, :::3307->3307/tcp, 0.0.0.0:6034->6034/tcp, :::6034->6034/tcp   readyset[root

Readyset 暴露了两个端口: 3307 和 6034。 Readyset 进程将在 3307 端口监听查询流量,并通过 /metrics 端点在 6034 端口发送监控数据。

然后,Readyset 将连接到您的数据库,并复制指定的表(即所有表或明确定义的表)。 根据这些表的大小以及 Readyset 和数据库之间的网络连接情况,这可能需要几秒到几小时的时间。

要检查表格是否已导入,请执行以下操作:

代码语言:bash复制
shell> docker logs readyset

当你看到:INFO replicators::noria_adapter: MySQL connected代表已准备好开始缓存查询。

或者,你用MySQL客户端访问3307端口,执行SHOW READYSET STATUS命令:

代码语言:bash复制
mysql> SHOW READYSET STATUS;
 ---------------------------- --------------------------- 
| Variable_name              | Value                     |
 ---------------------------- --------------------------- 
| Database Connection        | Connected                 |
| Connection Count           | 1                         |
| Snapshot Status            | Completed                 |
| Maximum Replication Offset | mysql-bin.000009:34960586 |
| Minimum Replication Offset | mysql-bin.000009:34610809 |
| Last started Controller    | 2024-08-19 01:28:48 UTC   |
| Last completed snapshot    | 2024-08-19 01:28:48 UTC   |
| Last started replication   | 2024-08-19 01:28:48 UTC   |
 ---------------------------- --------------------------- 
8 rows in set (0.62 sec)

查看该Snapshot Status列。如果快照成功完成,它将报告Completed

现在 Readyset 已准备好开始缓存查询。

3.在 Readyset 中缓存查询

用MySQL客户端连接上3307端口(Readyset端口),将线上的慢SQL在 Readyset 里运行,并执行SHOW PROXIED QUERIES命令

代码语言:sql复制
mysql> SHOW PROXIED QUERIES;
 -------------------- ------------------------------------------------------------------------------------------------ -------------------- ------- 
| query id           | proxied query                                                                                  | readyset supported | count |
 -------------------- ------------------------------------------------------------------------------------------------ -------------------- ------- 
| q_4c1cf3b8080fe634 | SELECT * FROM `test`.`t1` JOIN `test`.`t3` ON (`t1`.`id` = `t3`.`id`) WHERE (`t1`.`name` = $1) | yes                |     0 |
| q_906fa3045243ea2f | desc t1                                                                                        | unsupported        |     0 |
| q_ce39192051ca85ed | SELECT DATABASE()                                                                              | unsupported        |     0 |
| q_7da7d6ae3e899256 | SELECT count(*) FROM `t1` WHERE `id` IN (SELECT `id` FROM `t3`)                                | unsupported        |     0 |
| q_95e54bea818ecaa6 | SELECT count(*) FROM `t1`                                                                      | unsupported        |     0 |
| q_c4546a3773bfb40c | SELECT * FROM `test`.`t1` JOIN `test`.`t3` ON (`t1`.`id` = `t3`.`id`)                          | unsupported        |     0 |
| q_29a1660186d5c04b | SELECT * FROM `t1`                                                                             | unsupported        |     0 |
| q_9688f018b86e697b | SELECT * FROM `t3`                                                                             | unsupported        |     0 |
| q_adbda9f38a04a705 | SELECT * FROM `test`.`t1` JOIN `test`.`t3` ON (`t1`.`id` = `t3`.`id`) WHERE (`t1`.`cid` = $1)  | pending            |     0 |
 -------------------- ------------------------------------------------------------------------------------------------ -------------------- ------- 
9 rows in set (0.00 sec)

观察readyset supported列,如果为Yes,代表该SQL支持缓存。如果值处于待定状态,请再次检查,直到看到是或否。 如果数值等待超过 15 秒,则不支持查询。

4.创建SQL缓存

要缓存查询,请使用:

代码语言:sql复制
CREATE CACHE FROM <query id>;

这里以q_4c1cf3b8080fe634为例

代码语言:sql复制
mysql> CREATE CACHE FROM q_4c1cf3b8080fe634;
Query OK, 0 rows affected (0.68 sec)

5.查看缓存查询

代码语言:sql复制
mysql> SHOW CACHESG;
*************************** 1. row ***************************
         query id: q_36d53f6aa2b555c8
       cache name: q_36d53f6aa2b555c8
       query text: SELECT `test`.`t1`.`id`, `test`.`t1`.`name`, `test`.`t3`.`id`, `test`.`t3`.`jdoc` FROM `test`.`t1` JOIN `test`.`t3` ON (`test`.`t1`.`id` = `test`.`t
3`.`id`) WHERE (`test`.`t1`.`id` = $1)fallback behavior: fallback allowed
            count: 0
*************************** 2. row ***************************
         query id: q_c50ffddbdedb51f0
       cache name: q_c50ffddbdedb51f0
       query text: SELECT count(*) FROM `test`.`title_ratings` JOIN `test`.`title_basics` ON (`test`.`title_ratings`.`tconst` = `test`.`title_basics`.`tconst`) WHERE (
(`test`.`title_basics`.`startyear` = $1) AND (`test`.`title_ratings`.`averagerating` > 5))fallback behavior: fallback allowed
            count: 0
*************************** 3. row ***************************
         query id: q_4c1cf3b8080fe634
       cache name: q_4c1cf3b8080fe634
       query text: SELECT `test`.`t1`.`id`, `test`.`t1`.`name`, `test`.`t3`.`id`, `test`.`t3`.`jdoc` FROM `test`.`t1` JOIN `test`.`t3` ON (`test`.`t1`.`id` = `test`.`t
3`.`id`) WHERE (`test`.`t1`.`name` = $1)fallback behavior: fallback allowed
            count: 0
3 rows in set (0.01 sec)

6.测试

分别在 ReadySet 3307端口上,和后端MySQL端口上 ,执行刚才缓存的慢SQL,对比执行时间,你会发现缓存后的SQL秒级出结果。

初步测试表明,ReadySet 的有效性在第一次执行查询后,缓存机制可以充分发挥作用时就会变得非常明显。

0 人点赞