sbe 详解_内部简单二进制编码(SBE)

sbe 详解

SBE是用于金融行业的非常快速的序列化库,在本博客中,我将介绍一些使其快速发展的设计选择。

序列化的全部目的是对消息进行编码和解码,并且有很多可用的选项,例如XML,JSON,Protobufer,Thrift,Avro等。

XML / JSON是基于文本的编码/解码,在大多数情况下都很好,但是当延迟很重要时,这些基于文本的编码/解码就会成为瓶颈。

Protobuffer / Thrift / Avro是二进制选项,使用非常广泛。

SBE也是二进制的,是基于机械同情而构建的,以利用底层硬件(CPU缓存,预取程序,访问模式,管线指令等)的优势。

CPU和内存革命的小历史。

我们的行业看到了功能强大的8位,16位,32位,64位处理器,现在普通的台式机CPU可以执行近数十亿条指令,只要程序员能够编写程序来生成这种类型的负载即可。 内存也变得便宜,获得512 GB服务器非常容易。

我们必须改变编程方式以利用所有这些东西,数据结构和算法也必须改变。

让我们潜入sbe。

全栈方法

大多数系统依赖于运行时优化,但是SBE已采用全栈方法,并且第一级优化由编译器完成。

预算局

模式 – XML文件,用于定义消息的布局和数据类型。

编译器 –将模式作为输入并生成IR。 在这一层中发生了很多魔术,例如使用最终/常量,优化的代码。

消息 –实际消息被缓冲区包装。

全栈方法允许在各个级别进行优化。

无垃圾或少垃圾

这对于低延迟系统非常重要,如果不注意它,则应用程序将无法正确使用CPU缓存,并且可能进入GC暂停状态。

SBE是围绕flyweight模式构建的,它全部与重用对象有关,以减轻JVM上的内存压力。

它具有缓冲区的概念,可以重复使用,编码器/解码器可以将缓冲区作为输入并对其进行处理。 编码器/解码器不分配或分配很少(即在使用String的情况下)。

SBE建议使用直接/分出缓冲区使GC完全脱离图片,这些缓冲区可以在线程级别分配,并且可以用于消息的解码和编码。

缓冲区使用情况的代码段。

final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4096);final UnsafeBuffer directBuffer = new UnsafeBuffer(byteBuffer);
tradeEncoder        .tradeId(1).customerId(999).qty(100).symbol("GOOG").tradeType(TradeType.Buy);

缓存预取

CPU已内置基于硬件的预取器。 缓存预取是计算机处理器使用的一种技术,可通过在实际需要之前将指令或数据从较慢内存中的原始存储中提取到较快的本地内存中,从而提高执行性能。

从快速CPU缓存访问数据比从主存储器访问数据快许多个数量级。

等待时间,您应该知道的博客文章详细介绍了CPU高速缓存的速度。

如果算法正在流式传输并且所使用的基础数据像数组一样连续,则预取效果很好。 数组访问非常快,因为它是连续且可预测的

SBE使用数组作为基础存储,并将字段打包在其中。

预算局

数据以小批量的高速缓存行(通常为8个字节)移动,因此,如果应用程序要求1个字节,它将获得8个字节的数据。 由于数据打包在数组中,因此可以提前访问单字节预取数组内容,这将加快处理速度。

将预取器视为数据库表中的索引。 如果读取基于这些索引,则应用程序将受益。

流媒体访问

SBE支持所有原始类型,还允许定义大小可变的自定义类型,这允许编码器和解码器进行流传输和顺序传输。 从缓存行中读取数据具有很好的好处,并且解码器几乎不需要了解有关消息的元数据(即偏移量和大小)。

附带权衡的读取顺序必须基于布局顺序,尤其是在对可变类型的数据进行编码的情况下。

例如写正在使用以下顺序

tradeEncoder        .tradeId(1).customerId(999).tradeType(TradeType.Buy).qty(100).symbol("GOOG").exchange("NYSE");

对于字符串属性(符号和交换),读取顺序必须是第一个符号 ,然后是交换 ,如果应用程序交换顺序,则它将读取错误的字段,对于可变长度属性,另一项读取应仅为一次,因为它是流访问模式。

好东西是有代价的!

不安全的API

数组绑定检查可能会增加开销,但是SBE使用的是不安全的API,并且没有额外的绑定检查开销。

在生成的代码上使用常量

编译器生成代码时,它会预先计算内容并使用常量。 一个示例是字段偏移在生成的代码中,而不进行计算。

程式码片段

public static int qtyId(){return 2;}public static int qtySinceVersion(){return 0;}public static int qtyEncodingOffset(){return 16;}public static int qtyEncodingLength(){return 8;}

这需要权衡,这有利于性能,但不利于灵活性。 您无法更改字段顺序,必须在末尾添加新字段。

关于常量的另一个好处是,它们仅在生成的代码中存在,而在消息中却没有,这是非常有效的。

分支免费代码

每个内核都有多个并行运行的端口,几乎没有指令像分支,mod,除法那样阻塞。 SBE编译器生成的代码无需使用这些昂贵的指令,并且具有基本的指针碰撞数学功能。

没有昂贵指令的代码非常快,它将利用内核的所有端口。

Java序列化的样例代码

public void writeFloat(float v) throws IOException {if (pos + 4 <= MAX_BLOCK_SIZE) {Bits.putFloat(buf, pos, v);        pos += 4;    } else {dout.writeFloat(v);    }
}public void writeLong(long v) throws IOException {if (pos + 8 <= MAX_BLOCK_SIZE) {Bits.putLong(buf, pos, v);        pos += 8;    } else {dout.writeLong(v);    }
}public void writeDouble(double v) throws IOException {if (pos + 8 <= MAX_BLOCK_SIZE) {Bits.putDouble(buf, pos, v);        pos += 8;    } else {dout.writeDouble(v);    }
}

SBE的示例代码

public TradeEncoder customerId(final long value)
{buffer.putLong(offset + 8, value, java.nio.ByteOrder.LITTLE_ENDIAN);    return this;}
public TradeEncoder tradeId(final long value)
{buffer.putLong(offset + 0, value, java.nio.ByteOrder.LITTLE_ENDIAN);    return this;}

邮件大小上的一些数字。

类型级元帅.SerializableMarshal->大小267

类型类元帅.ExternalizableMarshal->大小75

输入类元帅SBEMarshall->尺寸49

SBE最紧凑且速度最快,SBE的作者声称它比Google proto缓冲区快20到50倍。

可提供SBE代码@ simple-binary-encoding

博客中使用的示例代码可在@ sbeplayground获得

翻译自: https://www.javacodegeeks.com/2018/06/inside-simple-binary-encoding-sbe.html

sbe 详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/333463.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php调用swf文件上传,swfupload-jquery-plugin AJAX+PHP 文件上传

var listitem>file.name (Math.round(file.size/1024) KB)>>>Pending;$(#log).append(listitem);$(this).swfupload(startUpload);})//绑定开始上传文件事件.bind(uploadStart, function(event, file){$(#log li#file.id).find(p.status).text(Uploading...);$(#lo…

aws lambda使用_使用AWS Lambdas扩展技术堆栈

aws lambda使用面对现实吧。 调试性能问题很困难&#xff0c;但是更难解决。 假设您发现了有害的代码&#xff0c;这些代码正在拖慢您的应用的运行速度。 最终会有一段时间&#xff0c;您发现此代码减速是同步的或线性执行的。 解决这些有问题的代码段的最有效方法之一就是将最…

Java声明定义抽象类/接口/继承/实现

文章目录声明定义抽象类声明定义接口派生类、抽象类、接口的继承要点声明定义抽象类 public abstract class CRMSystem {public abstract Client add(Client newGuy); //添加用户方法public abstract Event add(Event e, Client guy); //重载添加事件、用户方法public abstrac…

cuba开发_使用CUBA进行开发–与Spring相比有很大的转变?

cuba开发阅读另一个供内部公司使用的Web项目的要求时&#xff0c;您&#xff08;至少是我自己&#xff09;通常会看到一个很普通的集合&#xff1a;定义明确的数据存储结构&#xff08;或有时是现有的旧数据库&#xff09;&#xff0c;大量的数据输入形式&#xff0c;非常复杂的…

imagettftext php7,mac php7 imagettftext

Mac OS X 自带PHP环境gd库安装扩展freetype问题&#xff1a; “Call to undefined function imagettftext()”解决方法&#xff1a;curl -s [http://php-osx.liip.ch/install.sh](https://link.jianshu.com/?thttp://php-osx.liip.ch/install.sh) | bash -s 7.3sudo vim ~/.ba…

图片授权模式

RM、RF、PE是3种不同的图片授权模式&#xff0c;由图片卖家设定&#xff0c;图片买家根据自己的需要来进行选择。这三种模式是图片行业在发展过程中&#xff0c;经过对图片用户需求的不断总结而确定的。摄影师可以根据自己的销售意愿&#xff0c;在编辑图片的时候&#xff0c;对…

java线程池延期执行一次_Java使用者的延期执行

java线程池延期执行一次在前面的博客文章&#xff08;“ 延迟执行Java的供应商 “&#xff09;&#xff0c;我引用礁HORSTMANN的陈述书中‘ 的Java SE8为真的很急关于lambda表达式’&#xff0c;‘所有的lambda表达式的点被推迟执行 。’ Horstmann在最后一年为Dobb博士的杂志写…

python时间序列数据分析,Python数据分析之时间序列

Python数据分析之时间序列发布时间&#xff1a;2020-07-10 06:56:27来源&#xff1a;51CTO阅读&#xff1a;808作者&#xff1a;up4ever1. 时间序列类型时间戳(timestramp)即特定的时刻固定时期(period)如2018年1月或2018年1月1日时间间隔(interval)由起始和结束时间戳表示2. P…

java jdk 序列化_JDK 11:Java序列化的终结开始了吗?

java jdk 序列化在博客文章“ 将Google的协议缓冲区与Java结合使用 ”中&#xff0c;我引用了乔什布洛赫&#xff08;Josh Bloch&#xff09;的第三版的有效Java &#xff0c;他写道&#xff1a;“没有理由在您编写的任何新系统中使用Java序列化。” Bloch建议使用“跨平台结构…

php+ksort+返回true,PHP preg_replace函数

mixed preg_replace( mixed pattern, mixed replacement, mixed subject [, int limit] )在PHP中用来执行正则表达式的匹配以及替换的函数。可以返回一个正则表达式转换后的值。在subject中搜索pattern模式的匹配项&#xff0c;并用replacement模式进行替换。如果指定了 limit&…

下拉选择框

</select> 标签有一个属性 multiple&#xff0c;将其设置成 multiple"multiple" 按住 Ctrl 键即可实现多选。 请看例子&#xff1a; <html><head><meta http-equiv"Content-Type" content"text/html; charsetgb2312" />…

rest端点_REST:使用Controller端点?

rest端点在一般的REST架构中&#xff0c;基本概念是资源。 在资源之后&#xff0c;下一步是为这些资源开发一个统一接口&#xff0c;这在HTTP领域通常意味着&#xff1a; 创建为POST 阅读就是GET 更新为PUT&#xff08;或部分更新为PATCH&#xff09; 删除已删除 在现实世…

Java 字符串与整数之间的互相转换

1、如何将字符串String转化为整数int int i Integer.parseInt(str); int i Integer.valueOf(my_str).intValue(); 注: 字串转成Double, Float, Long的方法大同小异。 2、如何将字符串String转化为Integer Integer integerInteger.valueOf(i)3、如何将整数 int 转换成字串 Str…

hello world_建立无服务器的“ Hello World”功能

hello world无服务器 &#xff0c;功能即服务&#xff08;FaaS&#xff09;或仅具有云功能&#xff0c;就可以编写将在云中运行的代码。 您可以使用多种不同的语言&#xff08;例如JavaScript&#xff08;Node.js&#xff09;&#xff0c;Swift&#xff0c;Python&#xff0c;J…

xshell调出oracle安装界面,XShell+Xmanager实现在XShell中显示远程服务器的图形界面

你可以使用Xmanager软件&#xff0c;远程安装Oracle软件&#xff0c;Linux操作系统使用字符安装并不影响这种方式的使用。这个方案也可以大大优化你的Linux系统的性能&#xff0c;进而提高你的数据库性能。启动你的的Xmanager&#xff0c;我现在使用的是3.0版本&#xff0c;接收…

Oracle 数据库错误信息:动态执行表不可访问,本会话的自动统计被禁止

使用 PL/SQL 时, 每次第一次打开表的时候会提示以下信息&#xff1a; 动态执行表不可访问&#xff0c;本会话的自动统计被禁止&#xff0c;原因&#xff1a;V$SESSION,V$SESSTAT,V$STATNAME 没有被授权&#xff0c;没有权限访问这几张表&#xff0c;所以没有本法进行统计!那就…

jdk类加载器执行步骤_[JDK 11] jcmd中的类加载器层次结构详细信息

jdk类加载器执行步骤自从在JavaOne 2012上听说 jcmd以来&#xff0c;我就一直是命令行诊断工具jcmd的 粉丝 。 从那时起&#xff0c;我已经广泛使用了此工具&#xff0c;并多次在此博客中发布过此工具&#xff1a; jcmd&#xff1a;一个可以全部统治的JDK命令行工具 确定活动…

7445 oracle,Oracle 10g impdp 报 ORA-7445 [_INTEL_FAST_MEMCPY.A] 解决方法

在Oracle 10.2.0.4 以后的平台&#xff0c;我们在使用数据泵导入物化视图时&#xff0c;可能会遇到如下错误&#xff1a;...ksedmp: internal or fatal errorORA-7445: exception encountered: core dump [_intel_fast_memcpy.A()10][SIGSEGV] [Address not mapped to object] …

如何通过 PL/SQL Developer 将 Excel 数据导入 Oracle 对应的表中

首先将 Excel 文件另存为文本文件&#xff0c;然后在点击 PL/SQL Developer 菜单栏的【工具】-【文本导入器】&#xff0c;打开后如图所示&#xff1a; 上述步骤操作完之后&#xff0c;点击【到oracle的数据】&#xff1a;