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

Storing data in memcache to be accessed by different languages

本文关键字:语言 访问 数据 存储 memcache      更新时间:2023-10-16

我正在研究一个用以下语言编写组件的系统:

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

这些组件都使用(不经常更改)来自同一来源的数据,并且出于性能原因可以从memcache中缓存和访问。

因为不同的数据类型可能被不同的语言api存储到memcache中,我想知道是否将所有数据存储为字符串会更好(对象将存储为JSON字符串)。

然而,这本身可能会带来问题,因为字符串(几乎肯定)在不同的语言中有不同的内部表示,所以我想知道这个决定有多明智。

顺便说一句,我使用的是1个写器,多个读器的模式,所以并发性不是问题。

任何人(最好是做过类似事情的实际经验)建议在memcache中存储数据的最佳格式/方式,以便它可以被不同的编程语言使用?

memcached我认为主要只理解byte[],字节的表示在所有语言中都是相同的。您可以使用协议缓冲区或类似的库序列化对象,并以任何其他语言使用它。

无论选择的后端(memcached, mongodb, redis, mysql, carrier pigeon),最快速有效的方式来存储数据将是一个简单的数据块(所以后端不知道它)。不管是string, byte[], BLOB,其实都是一样的。

每种语言都需要一种商定的机制来将对象转换为可存储的数据格式。你:

  • 不应该建立自己的机制,那只是重新发明轮子。
  • 应该考虑"无效"对象是否会在后端结束。(要么是因为编写器中的错误,要么是因为以前版本中的对象仍然存在)

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

比较

JSON:

  • 提供数十种语言的库,有时是标准库的一部分。
  • 非常简单的格式-存储时人类可读,人类可写!
  • 不同系统之间不需要协调,只需要在对象结构上达成一致。
  • 在许多语言中不需要设置,例如PHP: $data = json_encode($object); $object = json_decode($data);
  • 没有固有模式,所以读者需要手动验证解码的消息。
  • 占用的空间大于协议缓冲区

协议缓冲区:

  • 为多种语言提供的生成工具
  • 最小尺寸-难以击败。
  • 通过.proto文件定义模式(外部)
  • 自动生成编码/解码接口对象,如c++: person.SerializeToOstream(&output);
  • 支持不同版本的对象模式来添加新的optional成员,这样现有的对象就不一定无效了。
  • 不是人类可读或可写的,所以可能更难调试。
  • 已定义的模式引入了一些配置管理开销。
Unicode

当涉及到Unicode支持时,两者都处理它没有问题:

  • JSON:通常将字符串中的非ascii字符转义为uXXXX,因此没有兼容性问题。根据库的不同,也可以强制使用UTF-8编码。
  • 协议缓冲区:似乎使用UTF-8,虽然我没有在谷歌的文档中找到3英尺高的字母的信息。

总结

选择哪一个将取决于您的系统将如何准确地表现,数据结构发生更改的频率,以及上述所有要点将如何影响您。

我不会说谎,你可以用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')))
    }
}