`
wqtn22
  • 浏览: 101082 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

erlang抽象码与basho的protobuf(一)使用

 
阅读更多

basho的riak是应用erlang编写的类dynamo kv存储,其实现贯彻了松耦合、模块化的特征,各类核心组件均可替换:

分布式组件riak_core可以用于构建其它的分布式应用,https://github.com/rzezeski/try-try-try是一个利用riak_core构建分布式应用的教学实例;

存储组件riak_kv和riak_serach是基于riak_core实现的分布式kv存储;

webmachine是基于mochiweb封装的通用REST框架;

protobuffs是erlang版的protocol buffers,最初位于https://github.com/ngerakines/erlang_protobuffs

bitcask是riak的默认存储引擎,通过nif实现了文件读写方法,之前本博客有提到过;

eleveldb通过nif实现了对leveldb的封装;

还有很多使用的组件,项目中能用的尽量拿来用吧。

此次将分析protobuffs这个组件,它本身完成的功能倒是容易描述清楚:“google的protocol buffers提供了跨语言的数据交换方法,支持c++/java/python,但是不支持erlang,basho帮我们实现了这个愿望,根据我们的proto文件描述的数据结构,产生对应的编解码erlang头文件和源文件”,但是看到它的实现后,我突然发现,erlang世界还有很多未知的地方需要探索。

言归正传,protocol buffers的资料请各位读者自行google,这里直接开始分析protobuffs的实现,版本为0.6.0。

先定义一个proto文件rds_la.proto如下:

 

package rds_la;

message la_record {

  required string name = 1;

  required int32 timestamp = 2;

  required string query = 3;

  required int32 query_time = 4;

  required int32 response_time = 5;

}

这是前日所开发的项目中用于传输一条日志记录的结构,其中name和query都是字符串,name最多64字节,而query最多1024字节。

利用protobuf附带的工具protoc-erl编译rds_la.proto得到rds_la_pb.hrl和rds_la_pb.erl。

rds_la_pb.hrl的内容主要为:

 

-record(la_record, {

    name = erlang:error({required, name}),

    timestamp = erlang:error({required, timestamp}),

    pb_query = erlang:error({required, pb_query}),

    query_time = erlang:error({required, query_time}),

    response_time = erlang:error({required, response_time})

}).

为rds_la生成了一个record,名为la_record,由于message la_record的所有域均为required,可以看到,protobuffs贴心的为record la_record每个域设置了默认值erlang:error({required, name}),而如果为optional,则不设置默认值,如果为repeated,也不会设置默认值,但是如果有值,该域将会是一个列表list。

rds_la_pb.erl的主要内容为:

 

-file("src/rds_la_pb.erl", 1).

 

-module(rds_la_pb).

 

-export([encode_la_record/1, decode_la_record/1]).

 

-export([encode/1, decode/2, iolist/2]).

 

-record(la_record,

        {name, timestamp, pb_query, query_time, response_time}).

 

 

encode_la_record(Record)

    when is_record(Record, la_record) ->

    encode(la_record, Record).

 

encode(la_record, Record) ->

    iolist_to_binary(iolist(la_record, Record)).

 

iolist(la_record, Record) ->

    [pack(1, required,

          with_default(Record#la_record.name, none), string, []),

     pack(2, required,

          with_default(Record#la_record.timestamp, none), int32,

          []),

     pack(3, required,

          with_default(Record#la_record.pb_query, none), string,

          []),

     pack(4, required,

          with_default(Record#la_record.query_time, none), int32,

          []),

     pack(5, required,

          with_default(Record#la_record.response_time, none),

          int32, [])].

...

enum_to_int(pikachu, value) -> 1.

 

int_to_enum(_, Val) -> Val.

 

decode_la_record(Bytes) when is_binary(Bytes) ->

    decode(la_record, Bytes).

 

decode(enummsg_values, 1) -> value1;

decode(la_record, Bytes) when is_binary(Bytes) ->

    Types = [{5, response_time, int32, []},

             {4, query_time, int32, []}, {3, pb_query, string, []},

             {2, timestamp, int32, []}, {1, name, string, []}],

    Decoded = decode(Bytes, Types, []), 

    to_record(la_record, Decoded). 

...

to_record(la_record, DecodedTuples) ->

    lists:foldl(fun ({_FNum, Name, Val}, Record) ->

                        set_record_field(record_info(fields, la_record), Record,

                                         Name, Val)

                end,

                #la_record{}, DecodedTuples).

...

以上便是生成的文件的内容,标注红色的地方需要读者注意,它们便是protobuffs_compile所生成的内容。

其中encode_la_record/1和decode_la_record/1是la_record的编解码函数;io_list/2则记录了编码时需要对record la_record的每个field需要做的动作;enum_to_int/2和int_to_enum/2用于enum值生成;decode/2记录了解码时生成的域应该放置在record la_record的哪个域;to_record/2记录了构造record la_record的过程。

不过这里有个很萌的pikachu是干嘛的?

未完待续...

 

分享到:
评论

相关推荐

    在erlang项目中使用protobuf例子

    标题中的“在erlang项目中使用protobuf例子”指的是在Erlang编程环境中使用Protocol Buffers(protobuf)这一数据序列化工具。protobuf是由Google开发的一种高效、跨语言的数据表示和序列化格式,它允许开发者定义...

    erlang版本的protobuf(erl_protobuffs)

    `erl_protobuffs`为Erlang开发者提供了一种高效的protobuf实现,增强了Erlang系统与外部世界的数据交换能力。通过其优化的编码和解码过程,以及对Erlang特性的良好适应,它在处理大量数据时表现出色,是构建高性能、...

    enif_protobuf:使用enif(Erlang nif)的Google Protobuf实现

    6. **集成到Erlang生态系统**:enif_protobuf使得Erlang系统能够无缝地与使用Protobuf的外部服务交互,如分布式系统中的数据交换。 在实际应用中,开发人员首先需要定义protobuf消息类型,然后使用Google提供的...

    改进erlang版的protobuf代码

    5. **编译工具链改进**:可能是对protobuf编译器的Erlang绑定进行了优化,使得生成的Erlang代码更加高效或者易于使用。 配套的文章地址(http://blog.csdn.net/mycwq/article/details/42122439)可能提供了更多关于...

    forms:一个简化使用Erlang抽象格式的库

    read/1与Erlang源文件(即带有.erl后缀的文件)和Erlang二进制文件(即带有.beam后缀的文件)一起使用。 下面的行将从Erlang的内部lists模块中读取表单。 forms : read ( lists ). 同样,以下行将从开发人员提供...

    erlang_protobuffs

    Erlang Protobuffs是一个用于Erlang的协议缓冲区(Protocol Buffers)实现,它允许Erlang程序与使用Google Protobuf编译器生成的消息格式进行交互。Google Protobuf是一种高效的数据序列化协议,广泛应用于跨语言的...

    erlang-protobuffs

    听说google proto buffer(以下简称protobuf)已经很久了,但是一直没有尝试使用它。其中一个原因是,项目组自己写了个打包和解包的工具,而且代码也简单,可以很方便的扩展到自动生成xml之类的配置文件,已经能很好...

    erlang程序设计与入门

    **Erlang程序设计与入门** Erlang是一种并发、函数式编程语言,主要用于构建分布式、高可用性、容错性强的系统。它的设计灵感来源于电信行业的需求,由瑞典爱立信公司于1986年开发。Erlang以其独特的并发模型、轻量...

    erlang编程 Introducing Erlang

    它负责解释Erlang字节码,提供内存管理、垃圾回收和并发调度等功能。 ### 10. 语言特性 Erlang的语法简洁,支持模式匹配、函数式编程、列表处理和递归等特性。它的动态类型系统和强大的类型推断让代码更加灵活。 ...

    最新最全rabbitmq与erlang版本匹配-2020-04-23.docx

    RabbitMQ是一种广泛使用的开源消息代理和队列服务器,它基于Erlang编程语言构建。Erlang以其并发能力、容错性和分布式特性而闻名,是实现RabbitMQ的理想选择。正确地匹配RabbitMQ和Erlang的版本对于确保系统的稳定性...

    C#与Erlang的群通信

    标题中的"C#与Erlang的群通信"指的是在编程领域中,使用C#和Erlang两种不同的编程语言进行集群或分布式系统间的通信。这两种语言各有特点,C#是微软开发的面向对象的编程语言,常用于Windows平台的开发,而Erlang则...

    Erlang与Mysql对接

    在Erlang中,与MySQL对接的关键在于选择合适的驱动程序,文件名为"erlang-mysql-driver"很可能是指一个Erlang的MySQL驱动库。这样的驱动库允许Erlang应用程序通过标准的数据库接口与MySQL进行通信。在Erlang中,这种...

    一个我自己学习Erlang的聊天室服务器及客户端代码

    本项目提供了一个使用Erlang编写的聊天室服务器端代码以及Java编写的客户端代码,这为我们深入理解Erlang的并发特性和Java与Erlang的交互提供了实践案例。 一、Erlang聊天室服务器端 1. 并发处理:Erlang的轻量级...

    并发需求下的Scala及Erlang语言的比较与使用

    ### 并发需求下的Scala及Erlang语言的比较与使用 在当今的高并发、大数据处理场景下,选择合适的编程语言对于系统性能至关重要。在众多编程语言中,Scala和Erlang因其强大的并发处理能力和函数式编程特性而受到关注...

    Erlang官网下载过慢

    Erlang是一种面向并发的、函数式编程语言,主要用于构建高度可扩展的、容错性强的分布式系统。在IT行业中,Erlang因其强大的实时性和处理大量并发连接的能力而被广泛应用于电信、互联网基础设施和实时系统。RabbitMQ...

    erlang25.0 windows版本

    Erlang是一种高级编程语言,特别适用于并发、分布式和实时系统。它由Ericsson公司开发,主要用于构建高可用性、容错性和可扩展性的软实时系统。Erlang的25.0版本是该语言的一个更新,针对Windows操作系统进行了优化...

    使用erlang连接ES的客户端

    在IT领域,Erlang是一种面向并发的、...总的来说,使用Erlang连接Elasticsearch客户端,可以帮助开发者高效地与ES服务器交互,利用Erlang的强大并发性和函数式编程特性,实现稳定、高性能的搜索和数据分析解决方案。

    erlang的小型游戏服务器

    本项目是一个基于Erlang的小型游戏服务器,使用了Mnesia数据库来存储游戏数据。 Mnesia是Erlang内置的一个分布式数据库管理系统,支持事务处理和实时查询,非常适合实时性要求高的游戏场景。在这个小型游戏服务器中...

    erlang22最新下载包

    Erlang是一种面向并发的、函数式编程语言,由瑞典电信设备制造商Ericsson为了实现分布式实时、高可靠性系统而开发。Erlang以其强大的并行处理能力、容错性和易于构建大规模分布式系统的特点,在电信、金融和互联网等...

    Erlang 20.3linux安装包

    Erlang是一种面向并发的、函数式编程语言,主要用于构建高度可扩展的、容错性强的分布式系统。在IT行业中,Erlang因其强大的实时性、并发性和内存管理机制而被广泛应用于网络通信、数据库系统以及消息中间件,如...

Global site tag (gtag.js) - Google Analytics