基于Protobuf共享字段的分包和透传零拷贝技术

技术基于Protobuf共享字段的分包和透传零拷贝技术 基于Protobuf共享字段的分包和透传零拷贝技术https://mp.weixin.qq.com/s/isOzeuwsn_-5TUqsLcgTn

基于Protobuf共享字段的分包和透明零拷贝技术

https://mp.weixin.qq.com/s/isOzeuwsn_-5TUqsLcgTnQ

基于Protobuf共享字段的分包和透传零拷贝技术,你了解吗

原朱文杰贾云社区2021-11-10

简介|本文介绍了Protobuf共享字段Guard的实现,并将其应用于中控/召回场景,获得了显著的CPU/延迟收益。即使不使用Guard,希望本文的经验和思路也能给读者带来一些帮助和参考。

引言

在推荐系统中,用户级字段往往需要贯穿整个环节,如实验参数、行为序列、用户画像等。

召回/过滤/分类模块都需要用户特征。这时候,自然最好的方法就是从请求一开始就一次性获取信息,然后传递给路透社。此前,作者经常写道:

const getrecordeq oReq;//来自rpcRankReq或oRankReqoRankReq.mutable _ user _人像()-copy from(oreq . user _人像());

这种透明传输自然是有益的,例如,如果下游需要用户特征,则不必再次请求每个请求。尤其是当上游发起分包时,用户级特征的透明传输可以显著降低下游获取用户特征的RPC开销。

然而,RPC开销减少了,再得陇望蜀想一想,是否能直接省去这个CopyFrom的开销呢

我们知道,protobuf提供了Allocated/Release系列接口,通过直接转移指针所有权,消除了Copy或Swap的开销。

换句话说,如果指针所有权是借出的而不是转移的,那么共享字段是可以实现的。借用实际上是使用前转移字段指针,使用后立即收回(收回所有权防止删除)。这是经典的卫士抽象。

当然,即使不使用Guard,我相信上面的想法也足以提供一些帮助。我们可以直接使用pb的接口来实现:

const getrecordeq oReq;//来自rpcgetrecommandreq=omplaceereq=const _ castgetrecordeq(oReq);RankReq oRankReqoRankReq.set _ allocated _ user _人像(oMutableReq.mutable _ user _人像());客户。等级(oRankReq);oRankReq.release _ user _人像();

对于一些比较复杂的操作,比如我想复制一些字段,共享一些字段,修改一些字段(分包场景),我们在下面给出我们的解决方案。

设计

我们的卫士提供了两个接口,即连接和分离。接口如下。通过pb的反射机制,release和set_allocated可以相互绑定,实现Guard销毁时的回滚。

void AttachField(Message * pMessage,int iFieldId,Message * pfieldvvalue);消息*详细字段(消息*消息,整数);

AttachField:首先,将允许的字段集借给pMesage,并在Guard析构后回滚并释放它,以防止双重删除。

DetachField:先借出pMessage的释放字段,在Guard析构后回滚返回,防止内存泄漏。

回滚的顺序是FILO,也就是严格的逆序(因为release和set_allocated不是严格对称的,如果循环可能会有问题)。

因为C的结构和破坏也是菲洛(https://ISOCPP.org/wiki/FAQ/dtors #

order-dtors-for-locals),一定要在pb初始化后再初始化Guard

这两个接口已经足够满足在我们的业务中存在的几种抽象:

(一)主调透传/分包

把上游传递的某个字段,零拷贝传入下游的请求。此时直接Attach字段即可。

//usecase:        const AReq  oAReq;        BReq oBReq;        SharePbFieldGuard guard;        guard.AttachField(oBReq, BReq::BigFieldId, const_castAReq (oAReq).mutable_bigfield());

(二)被调分包

控制某些字段不同,而其他字段共享/相同。为了避免拷贝大字段,我们可以在拷贝前先释放这些重的字段;拷贝结束后,把重字段共享给所有的分包。使用CopyFrom好处在于,我们不需要为所有新增的字段都手动判断,只需要特殊处理重的字段即可。

//usecase:        Req  oReq;        std::vectorReq vecMultiReq(n);        SharePbFieldGuard guard;        auto* pField = guard.DetachField(oReq, Req::BigFieldId);        for(auto  oSingleReq: multiReq)        {            oSingleReq.CopyFrom(oReq);            oSingleReq.set_field(...);            guard.AttachField(oSingleReq, Req::BigFieldId, pField);}

(三)多字段共享写法(以下是一段脱敏的实际代码)

由于操作的指针都是Message*类型,可以直接用容器存储pb index到字段指针的映射关系。通过循环即可共享所有重字段。

        std::vectoruint32_t vecHeavyField{};//初始化为一组fieldId        SharePbFieldGuard oGuard;        std::unordered_mapuint32_t, ::google::protobuf::Message* mapIndex2Message;        for(auto uField: vecHeavyField)        {            mapIndex2Message[uField] = oGuard.DetachField(oReq, uField);        }        for (auto  oSingleReq: vecReq)        {            oSingleReq.CopyFrom(oReq);            //shared filed            for(auto uField: vecHeavyField)            {                oGuard.AttachField(oSingleRecallReq, uField, mapIndex2Message[uField]);            }        }

展望

安全性:因为回滚时set_allocated会delete掉原本的字段,假如成环可能会很危险,如何侦测这种情况。

性能:是否存在不使用反射,就能自动绑定set_allocated和release的方法

Repeated字段支持:怎样处理Repeatd字段不同的反射接口

(https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.message#repeated-field-getters)

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/81981.html

(0)

相关推荐

  • CentOS 7.3上SQL Server vNext CTP 1.2如何安装

    技术CentOS 7.3上SQL Server vNext CTP 1.2如何安装这篇文章给大家分享的是有关CentOS 7.3上SQL Server vNext CTP 1.2如何安装的内容。小编觉得挺实用的,因此分享

    攻略 2021年11月15日
  • 有草有水的寓意好的字,带火的字而且寓意好的有哪些

    技术有草有水的寓意好的字,带火的字而且寓意好的有哪些“火”字旁的常用字有草有水的寓意好的字: 火(huo 4画)    灯(deng 16画)  灿(can 7画)    炀(yang 13画)  炜(wei 13画) 

    生活 2021年10月24日
  • 骠勇读音,brothers怎么读

    技术骠勇读音,brothers怎么读brother的读音为英 [ˈbrʌðə(r)] 美 [ˈbrʌðɚ] 骠勇读音。具体释义如下: brother 英 [ˈbrʌðə(r)] 美 [ˈbrʌðɚ] 1、名词 n.兄弟;

    生活 2021年10月29日
  • 抹胸内衣,穿抹胸裙如何隐藏内衣带

    技术抹胸内衣,穿抹胸裙如何隐藏内衣带1抹胸内衣、露双肩抹胸上衣/裙装系列露双肩抹胸的衣服看起来恐怕只能佩戴无肩带文胸,可真真怕一不留神来个滑落走光。姑娘们,方法是有滴:取一条闲置的内衣肩带,在内衣下缘多绕一圈,妥妥解决!

    生活 2021年10月20日
  • 如何进行Java中对HashMap的深度分析与比较

    技术如何进行Java中对HashMap的深度分析与比较如何进行Java中对HashMap的深度分析与比较,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。在

    攻略 2021年12月8日
  • 哪些业务适合租用香港服务器

    技术哪些业务适合租用香港服务器虽然大多数海外建站能从租用香港服务器中获得很多好处。然而,很多网站并不需要一开始就租用高性能的香港服务器,那么哪些业务适合使用香港服务器呢,下面就来介绍一下以下几个业务类型更适合使用香港服务

    礼包 2021年10月19日