在memcache中存储数据以供不同语言访问

2 投票
3 回答
1348 浏览
提问于 2025-04-17 03:25

我正在开发一个系统,这个系统里有几个部分是用不同的编程语言写的:

  • C
  • C++
  • C#
  • PHP
  • Python

这些部分都使用来自同一个来源的数据,这些数据不常改变,可以存储在memcache中,以提高性能。

因为不同的编程语言在存储数据到memcache时,可能会用不同的方式来处理不同的数据类型,所以我在想,是否应该把所有的数据都存储为字符串(对象会以JSON字符串的形式存储)。

不过,这样做可能会有问题,因为字符串在不同语言中的内部表示方式几乎肯定是不同的,所以我在考虑这个决定是否明智。

顺便提一下,我使用的是一个写入者和多个读取者的模式,所以并发问题不是我需要担心的。

有没有人(最好是有类似实际经验的人)能给我建议,如何在memcache中存储数据,以便不同的编程语言都能使用?

3 个回答

0

说实话,你可以用Redis来实现这个功能。Redis 是一个高性能的键值数据库,它可以让不同编程语言之间传输数据,使用了很多不同的客户端库。这些就是客户端库。下面是用Java和Python的示例代码。

编辑 1:代码没有经过测试。如果你发现错误,请告诉我哦 :)

编辑 2:我知道我没有使用Java的推荐Redis客户端,但这个观点还是成立的。

Python

import redis
r = redis.Redis()
r.set('test','123')

Java

import org.jredis.RedisException;
import org.jredis.ri.alphazero.JRedisClient;
import static org.jredis.ri.alphazero.support.DefaultCodec.*;

class ExampleCode{
    private final JRedisClient client = new JRedisClient();
    public static void main(String[] args) throws RedisException {
        System.out.println(toStr(client.get('test')))
    }
}
1

无论你选择什么样的后端存储(比如 memcached、mongodb、redis、mysql,甚至信鸽),存储数据的最快方式就是把数据简单地打包成一个块(这样后端就不需要了解数据的具体内容)。不管是 stringbyte[] 还是 BLOB,其实都是一样的。

每种编程语言都需要一个统一的方法来把对象转换成可以存储的数据格式,然后再转换回来。你需要注意:

  • 不要自己去造轮子,自己编写转换机制是多余的。
  • 要考虑是否会有“无效”的对象被存储到后端。(这可能是因为写入时的bug,或者是之前版本的对象还在)

在选择数据格式时,我推荐两种:JSONProtocol Buffers。因为它们的编码大小和编码/解码速度在所有可用编码中都是最小和最快的。

比较

JSON:

  • 有很多语言的库可用,有时甚至是标准库的一部分。
  • 格式非常简单 - 存储时人类可读,写的时候也很容易!
  • 不同系统之间不需要协调,只需对对象结构达成一致。
  • 在很多语言中不需要设置,比如 PHP: $data = json_encode($object); $object = json_decode($data);
  • 没有固定的结构,所以读取者需要手动验证解码后的消息。
  • 占用的空间比 Protocol Buffers 多。

Protocol Buffers:

  • 为几种语言提供了生成工具。
  • 体积小 - 很难被超越。
  • 通过 .proto 文件定义了外部结构。
  • 自动生成编码/解码的接口对象,比如 C++: person.SerializeToOstream(&output);
  • 支持不同版本的对象结构,可以添加新的 optional 成员,这样现有对象就不会失效。
  • 不易被人类读取或写入,因此可能更难调试。
  • 定义的结构会带来一些配置管理的开销。

Unicode

在 Unicode 支持方面,两者都能很好地处理:

  • JSON: 通常会把非 ASCII 字符转义为 \uXXXX,所以不会有兼容性问题。根据库的不同,也可能强制使用 UTF-8 编码。
  • Protocol Buffers: 似乎使用 UTF-8,不过我在谷歌的文档中没有找到明确的说明。

总结

你选择哪种格式取决于你的系统具体如何运作,数据结构变化的频率,以及上述所有因素对你的影响。

3

我觉得memcached主要只懂字节数组(byte[]),而字节在所有编程语言中的表示都是一样的。你可以使用协议缓冲区(protocol buffers)或者类似的库来把你的对象转换成字节,然后在其他语言中使用这些字节。我在我的项目中也这样做过。

撰写回答