简介
Readyset 是一种轻量级缓存解决方案,利用内存来存储缓存数据,实现复杂的 SQL 闪电般快速查询。
Readyset 介于应用程序和数据库之间,是一个 Cache 层。相当于 Redis/Memcached 的作用,但它不需要更改你的一行代码。
架构
Java/PHP应用程序 -> Readyset -> MySQL数据库
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 的有效性在第一次执行查询后,缓存机制可以充分发挥作用时就会变得非常明显。