Garland +

用 MySQL 的一张表实现一个 KV

我司使用 redis 的场景硬性要求是线上热数据,因为 redis 机器内存就那么大,提高内存利用率也只能放热数据了,不过具体怎么定义热数据,这个就具体情况具体讨论了。

但是回过头来看,我们很大一部分使用 redis 的场景的目的不是为了使用它作为一个高效的内存数据库的特性,而是它自带的 kv 形式的数据结构,也就是平时业务中会遇到的大量中间数据的需要存储为一个 list、set 这种的需求,而 mysql 作为 source of truth,是完全可以在一张表的基础上实现一个伪 redis 的。这里讲一下实现。

整理了下大部分的需求,发现绝大多数的使用场景为 list 和 set,这俩都是序列,里面含有多个 item,所以可以使用 key-item 作为 mysql 的一条记录,这样同时也方便后期对其他数据结构的扩展,对于有序可以增加一个标记位置的字段。

表设计

CREATE TABLE `misc_storage` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `name` int(11) unsigned NOT NULL,
    `value` text COLLATE utf8mb4_unicode_ci,
    `position` int(11) NOT NULL,
    `lock_version` int(11) unsigned NOT NULL DEFAULT '0',
    `create_time` datetime NOT NULL,
    `_created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `_updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

在实现操作 API 时,函数签名和返回值要和 redis-py 里对应的方法一致,方便调用者。

表上的读写方法

后面根据具体使用可以做一些优化,比如给 value 加上前缀索引索引之类的(SISMEMBER 要按 name 和 value 查询,数据量大之后效率很低)进一步优化性能

言:

Blog

Thoughts

Project