??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲免费精彩视频在线观看,亚洲国产91在线,久久亚洲AV成人无码国产最大http://www.tkk7.com/tw-ddm/category/55331.html<div id="ddm_subTitle"> <h2 class="catchline"> 哪怕没有办法一定有说法,<br/> q没有鸽子一定有乌鸦,<br/> 固执无罪&nbsp;梦想有h(hun),<br/> 让他们惊? </h2> </div>zh-cnFri, 12 Apr 2019 00:07:17 GMTFri, 12 Apr 2019 00:07:17 GMT60Nifi同步数据的几U方?/title><link>http://www.tkk7.com/tw-ddm/articles/433715.html</link><dc:creator>大大?/dc:creator><author>大大?/author><pubDate>Thu, 11 Apr 2019 09:27:00 GMT</pubDate><guid>http://www.tkk7.com/tw-ddm/articles/433715.html</guid><wfw:comment>http://www.tkk7.com/tw-ddm/comments/433715.html</wfw:comment><comments>http://www.tkk7.com/tw-ddm/articles/433715.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/tw-ddm/comments/commentRss/433715.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/tw-ddm/services/trackbacks/433715.html</trackback:ping><description><![CDATA[<span style="font-family: Arial; font-size: 10pt;">l常?x)遇到将Table从一个DB同步到另一个DB的需求,不同需求下Q可使用的处理方式会(x)有不同:(x)</span><br /><br /><span style="font-family: Arial; font-size: 10pt;">1. 使用特定的Processor</span><br /><span style="font-family: Arial; font-size: 10pt;">比如Upsert或自行开发的Processor</span><br /><br /><span style="font-family: Arial; font-size: 10pt;">2. 在Nifi程中自行构建SQL?qing)其l定参数</span><br /><span style="font-family: Arial; font-size: 10pt;">比如借用ConvertJsonToSQL的二ơ加?/span><br /><br /><span style="font-family: Arial; font-size: 10pt;">3. RouteOnAttribute的分?/span><br /><span style="font-family: Arial; font-size: 10pt;">最多能分出DeleteQUpdate是无能ؓ(f)力的Q而且q要考量资料序</span><br /><br /><span style="font-family: Arial; font-size: 10pt;">4. 仅新?+ DB层面的二ơ处理。这个其实是可以适用于所有情况,Nifi程贼简单,但DB上的东西多?/span><br /><span style="font-family: Arial; font-size: 10pt;">. 在收方加多一张tmp表,l构与正式表一_(d)但就是没有key。Nifi同步资料指到tmp?/span><br /><span style="font-family: Arial; font-size: 10pt;">. 在tmp表上加多TriggerQ在q里面CodingL制Insert、Update和Delete. Trigger里面除了不能Truncate TableQ其它啥都能?/span><br /><span style="font-family: Arial; font-size: 10pt;">. 加多一个Job或EventQ定时去清tmp表,防止它爆?/span><br /><img src ="http://www.tkk7.com/tw-ddm/aggbug/433715.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/tw-ddm/" target="_blank">大大?/a> 2019-04-11 17:27 <a href="http://www.tkk7.com/tw-ddm/articles/433715.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RouteOnAttribute的用?/title><link>http://www.tkk7.com/tw-ddm/articles/433714.html</link><dc:creator>大大?/dc:creator><author>大大?/author><pubDate>Thu, 11 Apr 2019 08:55:00 GMT</pubDate><guid>http://www.tkk7.com/tw-ddm/articles/433714.html</guid><wfw:comment>http://www.tkk7.com/tw-ddm/comments/433714.html</wfw:comment><comments>http://www.tkk7.com/tw-ddm/articles/433714.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/tw-ddm/comments/commentRss/433714.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/tw-ddm/services/trackbacks/433714.html</trackback:ping><description><![CDATA[<div style="display: inline-block;"><h5><span style="font-family: Arial; background-color: #ffffff; font-size: 10pt;">RouteOnAttribute</span></h5><span style="background-color: #ffffff; font-size: 10pt; font-family: Arial;">    q个lg的是用途是Ҏ(gu)Attribute的D行Route分流Q从输入输出的角度来看,它可以把一个Input分成多个Output出来Q它的分支不同于E序中的Switch语法Q而等效于多条的IF语句Q也是说若Output的条件全部都W合Q它是可以把1个输出Copy到多个输出的Q所以它也可以用于条件复制的应用上?br />    关于资料落地的文章里我有提到qRoute的用范_(d)它应该用在能够以Key做分支条件的场景Q也是说相同的Key一定会(x)走固定的Output出来Q这h不会(x)出现资料乱序的状c(din)下面有两个CZQ第一个是典型的分支用法,W二个比较有意思,它的作用相当于Oracle中的Decode语法<br /><br /></span><h5><span style="background-color: #ffffff; font-size: 10pt; font-family: Arial;">CZ1</span></h5></div><div><span style="font-size: 13.3333px;">    使用Route做流E的分支Q根据一个叫SO的栏位是否ؓ(f)I决定走不同的流E?左右的UpdateAttribute可以把它们想象成两个完全不同的处理流E来?<br /><br /><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/Route1.png" width="600" height="216" alt="" /><br /><br /><br /></span><span style="font-family: Arial; font-style: italic; background-color: #ffffff; font-size: 10pt;"><strong>    RouteOnAttribute</strong>Q?/span><span style="background-color: #ffffff; font-size: 10pt; font-family: Arial;">作用是根据Attribute的Bool值来军_是否q入该分?/span><br /><span style="font-size: 13.3333px;"><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/RouteOnAttributeProcessor1.png" width="600" height="443" alt="" /><br /></span><ul style="font-size: 12px; margin-left: 1em; background-color: #ffffff;"><li><span style="font-size: 8pt;"><font face="Comic Sans MS"><em>HasSO / NonSO</em></font><font face="Trebuchet MS, 宋体">Q这是我自行定义的两个Route名称 (不是属性名U?QValue是一个表辑ּQ若它的?trueQ则Output?x)进该Route</font></span></li><ul><li style="font-family: "Trebuchet MS", 宋体;"><span style="font-size: 8pt;">Nifi的表辑ּ语法不怎么好写Q官方的文档上有些东西ƈ不支?(不确定是不是Nifi版本~故)。这里还是可以看得出来就只是判断一个叫SO的Attribute的值是否ؓ(f)I?--- q记得有些Processor里面q有?Null Value Representation"的属性吧Q若是那里配?null"那这里也要与之匹配?/span></li></ul><li style="font-family: "Trebuchet MS", 宋体;"><span style="font-size: 8pt;">l过该Processor处理后,SO为空的会(x)走右端逻辑Q而不为空的则?x)走左段逻辑Q同时它?x)加多一个叫"RouteOnAttribute.Route"的AttributeQ内容即为Route名称<br /></span></li></ul><span style="font-size: 13.3333px;"><br /></span><h5><span style="font-size: 13.3333px;">CZ2Q?/span></h5><span style="font-size: 13.3333px;">    Ҏ(gu)多个栏位是否有?不ؓ(f)I?Q让它们能够q入不同的RouteQ后面再Ҏ(gu)Route名称d态的取|它的特点是Nifi程q没有出现分?Connection上是勾了所有的Route)Q只是ؓ(f)不同的数据设上了一个变量名U?br /><br /><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/Route2.png" width="600" height="298" alt="" /><br /><br /></span><span style="font-family: Arial; font-style: italic; background-color: #ffffff; font-size: 10pt;"><strong>    RouteOnAttribute</strong>Q?/span><span style="font-family: Arial; background-color: #ffffff; font-size: 10pt;">借用</span><span style="background-color: #ffffff; font-size: 10pt; font-family: Arial;">分支名称在后面搞事,q里相当于是l资料加上了一个变量名U?/span><br /><span style="font-size: 13.3333px;"><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/RouteOnAttributeProcessor2.png" width="600" height="442" alt="" /><br /></span><ul style="margin-left: 1em; background-color: #ffffff;"><li style="font-size: 12px;"><span style="font-size: 8pt;"><font face="Comic Sans MS"><em>MO / MODELFAMILY / UPN / USN</em></font><font face="Trebuchet MS, 宋体">Q这是定义的四个Route名称Q判断条仉很简单,只是不为空</font></span></li><ul><li style="font-size: 12px;"><span style="font-size: 8pt;"><font face="Trebuchet MS, 宋体">值得注意的是q?个条件ƈ非是互斥条gQ比如有一W资料它的MO、USN都不为空Q那么就?x)同时进入两个Routeq行输出Q所?span style="color: red;">OutputW数?x)?</span></font></span></li><span style="font-size: 13.3333px; font-size: 13.3333px;"></span><li><font face="Trebuchet MS, 宋体"><span style="font-size: 10.6667px;">下面q是q入UPNq个Route后的资料上的Attribute: "RouteOnAttribute.Route"<br /><br /><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/Route3.png" width="600" height="405" alt="" /></span></font></li></ul></ul><span style="font-size: 13.3333px;"><br /><br /></span><span style="font-family: Arial; font-style: italic; background-color: #ffffff; font-size: 10pt;"><strong>    UpdateAttribute</strong>Q?/span><span style="background-color: #ffffff; font-size: 10pt; font-family: Arial;">比较_ֽ的用?/span><br /><span style="font-size: 13.3333px;"><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/UpdateAttributeProcessor4.png" width="600" height="442" alt="" /><br /></span><ul style="font-size: 12px; margin-left: 1em; background-color: #ffffff;"><li><span style="font-size: 8pt;"><font face="Comic Sans MS"><em>mqttTopic</em></font><font face="Trebuchet MS, 宋体">Q这是定义的一个MQTT的Topic变量Q它的内Ҏ(gu)可变动的Q会(x)Ҏ(gu)Route的不同生不同的l果</font></span></li><ul><li><span style="font-size: 8pt;"><font face="Trebuchet MS, 宋体">MO/MODELFAMILY/UPN/USNq?个条件有M不ؓ(f)I,则会(x)要求推送TopicQ?xxxx/【Type?【Value?yyyy</font></span></li><span style="font-size: 13.3333px;"></span><ul><li><span style="font-size: 8pt;"><font face="Trebuchet MS, 宋体">【Type? ?mo"?modelfamily"?upn"?usn"q四个g一</font></span></li><span style="font-size: 13.3333px;"></span><li><span style="font-size: 8pt;"><font face="Trebuchet MS, 宋体">【Value? 为MO/MODELFAMILY/UPN/USNq四个Attribute的取?(?${MO} / ${MODELFAMILY} / ${UPN} / ${USN} 的?Q这里用了双层<span style="color: red;">${${"RouteOnAttribute.Route"}}</span>的取值方法来实现动态的取用变量?/font></span></li></ul></ul></ul><span style="font-size: 13.3333px;"><br /><br /><br /></span></div><img src ="http://www.tkk7.com/tw-ddm/aggbug/433714.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/tw-ddm/" target="_blank">大大?/a> 2019-04-11 16:55 <a href="http://www.tkk7.com/tw-ddm/articles/433714.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Kafka资料落地至MariaDB Q带Key的新增、修改和删除Q?/title><link>http://www.tkk7.com/tw-ddm/articles/433713.html</link><dc:creator>大大?/dc:creator><author>大大?/author><pubDate>Thu, 11 Apr 2019 07:40:00 GMT</pubDate><guid>http://www.tkk7.com/tw-ddm/articles/433713.html</guid><wfw:comment>http://www.tkk7.com/tw-ddm/comments/433713.html</wfw:comment><comments>http://www.tkk7.com/tw-ddm/articles/433713.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/tw-ddm/comments/commentRss/433713.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/tw-ddm/services/trackbacks/433713.html</trackback:ping><description><![CDATA[<h5>需求:(x)</h5><span style="font-family: Arial; font-size: 10pt;">    比较前一文章来_(d)仅加多Delete的行为。例如我仅需要Status=1的资料,所以对于资料落地来Ԍ最合适的莫过于下面这PTable也可以自动保持最量的有效资?br /></span><span style="font-family: Arial; font-size: 10pt;">    1. 新资料Status=0Q执行Insert;<br /></span><span style="font-family: Arial; font-size: 10pt;">    2. 资料修改Status=0Q执行Update;<br /></span><span style="font-family: Arial; font-size: 10pt;">    3. 资料状态变更Status=1Q执行Delete;<br /></span><span style="font-family: Arial; font-size: 10pt;">    4. 若资料状态重新变更ؓ(f)0Q则又会(x)执行Insert;</span><br /><br /><h5><span style="font-family: Arial; font-size: 10pt;">思\Q?/span></h5><span style="font-family: Arial; font-size: 10pt;">  </span><span style="font-family: Arial; font-size: 10pt;">  按理来说Q只要通过分支Route可以将Insert/Update与Delete作业分成两条Nifi支流(看网上确实有很多q么整法?Q但是用Route有一个问题处理不了,那就是资料顺序的正确性你是无法保证的。对于小数据量的场景来说Q每WKey的多ơ操作间隔可能会(x)比较长,所以它不会(x)有什么问题,但大数据量的情况下,两同相同Key值的资料走Route后被处理的顺序؜乱就?x)造成最l资料结果的异常(比如应该是先Insert再DeleteQ结果却是发现资料还w在Table?。而大数据量在使用Kafka做ؓ(f)数据源时׃可避免会(x)出现Q即使业务数据量实不大Q但对于U篏了好几天的数据再q行接收Ӟ那一瞬间的数据量也会(x)是很大的?br /></span><span style="font-size: 10pt; font-family: Arial;">   所以我们能做的是动态决定执行Delete和Insert?/span><br /><br /><h5>解决Ҏ(gu)Q?/h5><span style="font-family: Arial; font-size: 10pt;">虽然?a href="http://www.tkk7.com/tw-ddm/articles/433711.html">前一?/a>来说差异不大Q但Nifi程上却有很大不同,下面?x)详l描qCؓ(f)什么要q样?br /><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/ReceiveData_Delete.png" alt="" /><br /><br /><br /></span><h5><span style="font-family: Arial; font-size: 10pt;">Processor?qing)其讑֮Q?/span></h5><em style="font-family: "Comic Sans MS"; font-size: 13.3333px; background-color: #ffffff;"><strong>    ConsumeKafkaRecord、SplitJson、Connection、EvaluateJsonPath</strong></em><span style="font-family: "Trebuchet MS", 宋体; font-style: italic; background-color: #ffffff; font-size: 10pt;">Q?/span><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;">与前一章的一P只是不同数据下解析的属性有所不同Q这里不再详q?/span><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;"><br /></span><span style="font-family: Arial; font-size: 10pt;"><br /></span><em style="font-family: "Comic Sans MS"; font-size: 13.3333px; background-color: #ffffff;"><strong>    UpdateAttribute</strong></em><span style="font-family: "Trebuchet MS", 宋体; font-style: italic; background-color: #ffffff; font-size: 10pt;">Q?/span><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;">作用是从Kafka中Consume?以Record的Ş态)Q这里用Record是因为源数据是以Record的方式存上去?(Avro Schema)<br /><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;"><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/UpdateAttributeProcessor2.png" width="600" height="442" alt="" /></span></blockquote></span><ul style="font-size: 12px; font-family: "Trebuchet MS", 宋体; margin-left: 1em; background-color: #ffffff;"><li><span style="font-size: 8pt;"><em>SQL1</em>Q这才是q次花招的关键,在这里根据STATUS自行构徏SQL语句</span></li><ul><li><span style="font-size: 8pt;"><em>Status=0</em>Q构建的是Delete From xxx Where Key1=? and Key2=? q样的删除语?/span></li><li><span style="font-size: 8pt;"><em>Status!=0</em>Q构建的是Replace Into xxx (Key1,Key2,col3,col4) Values ( ?, ?, ?, ?) q样的Insert or Update语句</span></li></ul><li>l此Processor处理后,资料落地所需的SQL构建好了,后箋的问题就是如何去l定参数和执?/li></ul><br /><em style="font-family: "Comic Sans MS"; font-size: 13.3333px; background-color: #ffffff;"><strong>    ReplaceText</strong></em><span style="font-family: "Trebuchet MS", 宋体; font-style: italic; background-color: #ffffff; font-size: 10pt;">Q?/span><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;">作用是对FlowFileq行文本替换Q这里用它来直接生我所需的JSON内容</span><br /><span style="font-family: Arial; font-size: 10pt;"><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><span style="font-family: Arial; font-size: 10pt;"><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/ReplaceTextProcessor2.png" width="600" height="442" alt="" /></span></blockquote></span><ul style="font-family: "Trebuchet MS", 宋体; margin-left: 1em; background-color: #ffffff;"><li style="font-size: 12px;"><span style="font-size: 8pt;"><em>Search Value</em>Q这里用的是Default?/span>(?s)(^.*$)Q作用就是把原先的整份文件全部换?/li><li style="font-size: 12px;"><em style="font-size: 8pt;">Replacement Value</em><span style="font-size: 8pt;">Q这里放的就是一个固定结构的JSONQ可以看到里面的属性值都是用的Attribute (它们的值来源于前面的EvaluateJsonPath从源JSON文g中的提取)</span></li><ul style="font-size: 12px;"></ul><li><span style="font-size: 10.6667px;">l心的朋友可以发现这里是与前一文章的最大不同,q里没有使用AttributeToJsonȝ接生JSON文gQ而用的是更加笨拙的方式</span></li><ul><li><span style="font-size: 10.6667px;">前面的文章有提过Q我们生的Attribute以及(qing)AttributeToJson所生成JSON中各属性的序问题Q结论是怎么搞它都不是我所惌到的序。但是ConvertJsonToSQLq个东东却很实在Q它确实实是按JSON中属性的序ȝ成的SQL以及(qing)参数名称(q记得参数名Usql.args.</span><span style="font-size: 10.6667px; color: red;">1</span><span style="font-size: 10.6667px;">.value中的q个序</span><span style="font-size: 10.6667px; color: red;">1</span><span style="font-size: 10.6667px;">?Q所以问题就来了Q?/span><br /></li><ul><li style="font-size: 12px;">SQL׃必须要有Delete和ReplaceQ所以它们的参数个数一定是不同的,而Delete压的参数又是我们的KeyQ所以就必须要保证ConvertJsonToSQL生成属性的序Q这h们才能够保证我们的两个Key一定会(x)是sql.args.1和sql.args.2</li></ul><span style="font-family: Arial; font-size: 10pt;"></span><ul><li style="font-size: 12px;">换句话说Q如果AttributesToJson若是能够保证JSON属性顺序的话,那就不用q么费劲</li></ul></ul></ul><span style="font-family: Arial; font-size: 10pt;"><br /></span><em style="font-family: "Comic Sans MS"; font-size: 13.3333px; background-color: #ffffff;"><strong>    ConvertJsonToSQL</strong></em><span style="font-family: "Trebuchet MS", 宋体; font-style: italic; background-color: #ffffff; font-size: 10pt;">Q?/span><span style="font-family: "Trebuchet MS", 宋体; font-size: 13.3333px; background-color: #ffffff;">与前文一P以Insert的方式生成SQL和绑定参数即?/span><br /><span style="font-family: Arial; font-size: 10pt;"><br /></span><em style="font-family: "Comic Sans MS"; font-size: 13.3333px; background-color: #ffffff;"><strong>    UpdateAttribute</strong></em><span style="font-family: "Trebuchet MS", 宋体; font-style: italic; background-color: #ffffff; font-size: 10pt;">Q?/span><span style="background-color: #ffffff;"><font face="Trebuchet MS, 宋体"><span style="font-size: 10pt;">l于用到了它的Delete功能Q作用是清除掉多余的SQLl定参数</span></font><br /><blockquote style="font-family: "Trebuchet MS", 宋体; font-size: 10pt; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;"><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/UpdateAttributeProcessor3.png" width="600" height="441" alt="" /><br /></span></blockquote></span><ul style="font-family: "Trebuchet MS", 宋体; margin-left: 1em; background-color: #ffffff;"><li style="font-size: 12px;"><span style="font-size: 8pt;"><em>Delete Attributes Expression</em>Q这里我Ҏ(gu)Delete的条?STATUS=0)d除多余的SQLl定参数</span></li><ul><li style="font-size: 12px;"><span style="font-size: 8pt;">q里的写法比较死Q我Hard-code删除掉大?的其它所有参?" </span><span style="font-size: 8pt; color: red;">*</span><span style="font-size: 8pt;"> "</span><span style="font-size: 8pt;">是一个通配W," </span><span style="font-size: 8pt; color: red;">|</span><span style="font-size: 8pt;"> "是一个多条g的间隔符)Q感觉上q有更好的写?/span></li></ul><li style="font-size: 12px;"><span style="font-size: 8pt;">x我们可以保证绑定参数的数量与SQL语法参数个数一?(不一致它ȝ你看)</span></li><ul style="font-size: 12px;"></ul></ul><span style="background-color: #ffffff;"></span><span style="background-color: #ffffff;"><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;"><br /></span></span><em style="font-family: "Comic Sans MS"; font-size: 13.3333px; background-color: #ffffff;"><strong>    PutSQL</strong></em><span style="font-family: "Trebuchet MS", 宋体; font-style: italic; background-color: #ffffff; font-size: 10pt;">Q?/span><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;">q里仍然是执行SQLQ这里用配|参数的形式让它执行我们的SQL</span><br /><span style="font-family: Arial; font-size: 10pt;"><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><span style="font-family: Arial; font-size: 10pt;"><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/PutSQLProcessor2.png" width="600" height="440" alt="" /></span></blockquote></span><span style="font-family: Arial; font-size: 10pt;"><br /></span><ul style="font-family: "Trebuchet MS", 宋体; margin-left: 1em; background-color: #ffffff;"><li style="font-size: 12px;"><span style="font-size: 8pt;"><em>SQL Statement</em>Q前面用UpdateAttribute产生的SQL1参数Q它?x)根据STATUS=0d断是使用DELETEq是REPLACE语法</span></li><ul><li style="font-size: 12px;"><span style="font-size: 8pt;">q个属性压上后Q无论SQL1是不是ؓ(f)I,q个lg都不?x)再ȝFlowFile的内?I属性时是把FlowFile的内容当成SQLL行的)</span></li></ul></ul><img src ="http://www.tkk7.com/tw-ddm/aggbug/433713.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/tw-ddm/" target="_blank">大大?/a> 2019-04-11 15:40 <a href="http://www.tkk7.com/tw-ddm/articles/433713.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Kafka资料落地至MariaDB Q带Key的新增、修改)http://www.tkk7.com/tw-ddm/articles/433711.html大大?/dc:creator>大大?/author>Thu, 11 Apr 2019 06:14:00 GMThttp://www.tkk7.com/tw-ddm/articles/433711.htmlhttp://www.tkk7.com/tw-ddm/comments/433711.htmlhttp://www.tkk7.com/tw-ddm/articles/433711.html#Feedback0http://www.tkk7.com/tw-ddm/comments/commentRss/433711.htmlhttp://www.tkk7.com/tw-ddm/services/trackbacks/433711.html需求:(x)    接收Kafka资料Q资料具有Key?多列)Q有新增、修改但无删除,需要同步落地至MariaDB
解决Ҏ(gu)(仅新增、修?Q?/h5>    q个场景是最常见的,资料不会(x)有被删除的状态,所有的更新只有Insert Or Updateq两U状态,先上实例的图 (两边的LogMessage是ؓ(f)了接收FailQ有感叹h避免一起开启的时候它也被开?---q样failure的讯息就不会(x)再卡在Connection中了)


思\Q?/span>
    因ؓ(f)记录只有新增和修改两U状态,理论上说q两U的SQL非常接近Q所以可以做以下考量
    1. Processor层面是否支援Update Or Insert
      > 查网上讯息有个叫UpsertQ不q在Nifi中查找,只有一个支援Mongo的组件具有这个功?/span>
    2. DB层面是否支援
      > Maria DB有个 "REPLACE INTO" 的语法是可以支持Insert Or UpdateQ虽然简单看了下介绍说是?x)依主键或唯一索引d做定位,如果定位到已l存在则先做删除再进行新增(伪UpdateQ,但确实可以达成我们的目的Q不是吗Q?/span>

Processor?qing)其讑֮Q?/span>
    ConsumeKafkaRecordQ作用是从Kafka中Consume?以Record的Ş态)Q这里用Record是因为源数据是以Record的方式存上去?(Avro Schema)
  • Kafka BrokersQKafka的Broker列表Q多个Broker以逗号分隔Q类似www.broker1.com:9193,www.broker2.com:9193q样的Ş式配|?/font>
  • Topic NameQ需要Consume的Kafka Topic名称
  • Record Reader/WriterQ关于Record所需要设定的Reader和W(xu)riterQ要先行在Configure中设定,当然也要讑֮好Schema  
  • Group IDQConsumer所要设定的IDQ这个的讑֮要依Kafka的配|来Q现在我们一般就只有单个的PartitionQ所以会(x)要求每个Processor都设定有不同
  • Offset ResetQ需要设定ؓ(f)"earliest"Q这样就?x)依GroupID没有收过的资料来q行收取Q否则就只会(x)收新推上ȝ资料。第一ơ玩的兄弟经常坑在GroupID和Offset Resetq两上Q若是收不到资料则有  可能是GroupID没有换成新的(旧的已经收过一ơ就不会(x)重新再收)Q或者是Offset Reset = latest又没有新资料推上去~~~
  • Max Poll Records和SCHEDULING中的Run ScheduleQ需要根据实际接收的速度来进行调整。经q观察发现Consume的速度快Q但整个Nifi Flow的速度?x)卡在其它需要做解析或读写DB的Processor?(通常解析JSON?x)是前面的关?Q所以Q由Consumer的高速读取就?x)造成整个Nifi程在后D被卡住。造成q个的主要原因其实就在于kafka处理的高速上Q所以当有新换GroupID或新程ӞKafka上积累的量资料׃(x)在一瞬间被接收下来,然后是各种U?(其实U了也没事,它会(x)自动向上推,让前一个Processor停止处理)?br />
    • 若是常态下的资料推送量已l超q了你的Nifi处理速度Q那么就要考量使用多个U程处理或者是从源头的Kafka上就把资料分割开?nbsp; 
    • SCHEDULING的Cocurrent TasksQ这个Default=1Q就是当前Processor需要开h的线E数。但是这个设|需要当心,你需要仔l考量q你的资料流是否允许乱序 (多线E时当然不可能还能保证资料处理的序)Q所以它是仅适用于不Care资料处理序的场景,例如每笔Key只?x)有一W资料,而且哪笔资料先收后收无所?/span>

    SplitJsonQ作用就只是单的把一个JSON数组切开成单个的JSON。Consume出来的会(x)是个数组Q这跟你存放q去的单W讯息是不是数组没什么关pR?/span>

    ConnectionQ就是Processor中的那根带箭头的q线Q它的作用是q接不同的Processorq且它还h~存池的的一个用途,除了把数据从A导流向B(ti)外,q可以将B暂时处理不动的资料存攑֜自带的缓存池中,若是~存池达C限,则Nifi?x)自动让A暂停处理直至B~过劲~~~
  • Back Pressure Object Threshold / Back Pressure Data Size ThresholdQ最大缓存的消息W数 / 最大缓存消息的体积Q两者Q一过׃(x)让上游Processor处理暂停
  • Available PrioritizersQ出入缓存池的顺序控ӞDefault是空Q通常来说都应该要设成FIFO先进先出的方?/span>
    • 不设定这个经怼(x)造成Nifi资料处理丢失的假象,A1,A2,A3,A4Q最后看到的不是A4而是A3Q会(x)让h以ؓ(f)A4被玩掉了Q其实只是A4被先处理Q而A3变成了最后一W状态。而且q种错误很难被发?!


    EvaluateJsonPath1Q这个元件的作用是解析JSONQ它也只能简单的解析Q想在Value中对取出来的值做一些处理好象是不允许的....
  • DestinationQ表C析出来的内容是成为AttributeQ还是直接替换Flow File内容Q这里设定是做ؓ(f)属性,所以Processor处理后就可以在Flow File上看到多定义的那些属性以?qing)它们的?/span>
  • Return TypeQ返回值的cdQ这U简单从JSON中取值的可以使用Auto-detect卛_
  • Path Not Found BehaviorQ是说如果设定需要解析的JSON路径不存在时的处理行?/span>
  • Null Value RepresentationQ这个对于Null值的处理Q?"empty string"?x)将null设ؓ(f)I字W串(MO=)Q另外一?the string 'null'"则是?x)将null设ؓ(f)"null"q样的字W串 (MO="null")
  • MO/MODELFAMILY/....Q这些是我手工添加的属性名Uͼ需要根据JSON长样来设Q对应Value讑֮?.MO则是表示MO的值来源于JSONW一层的"MO"节点?/span>
    • 需要注意的一Ҏ(gu)属性名U貌似是?x)区分大写的,所以可以看到我全部使用的大?/span>
  • 截图是运行时态的ProcssorQ停止运行时PROPERTIES上会(x)有一?+ P点它卛_以新增自q属?br />
    • 有一Ҏ(gu)较奇怪的地方Q就是通过+L(fng)护进ȝ多个属性,它们的排列顺序却不是你手工新增的序Q这点引发另外一处的一个疑问,?x)在下面?br />
    EvaluateJsonPath2Q当然也是要从JSON中解析,只不q我是要把整个JSON的内定w保留下来Q由于它们要求的讑֮不同Q所以被q要撕成两个元g来做
  • DestinationQ这个设定仍然是属?/span>
  • Return TypeQjsonQ第一个解析元件虽然可以随意设|,但把q两U合q成一个元件ƈ使用Auto时就?x)报错,所以看hW一U简单属性实际上只支持Scalar?..
  • JSONDATAQ我定义的一个属性名Uͼ注意Value中设定的"@"W号Q它表示整䆾FlowFile的内?前面已经转成一个JSON)
  • q个JSONDATA是因为我的需求,因ؓ(f)Kafka上的资料来源于其它系l,而我其实只需要其中的量几个栏位 (前一个EvaluateJsonPath解析的那?Qؓ(f)了备查数据上的其它栏位以?qing)在后箋使用Q所以才要把整䆾JSON都保留到DB中去 (说得q么高端Q实际的原因却是他们的JSON属性是用程序硬拼字串拼出来的,有的东西实在是在Nifi中搞不出?.....)

    UpdateAttributeQ元件用途是对FlowFile的Attrubuteq行修改Q这里是拿来对解析出来的D行再加工以及(qing)d新属?/span>
  • Delete Attributes ExpressionQ这个属性如果有讄pCProcessor为Delete属性的状态,?x)忽略你新加的那些属性处理,只专心做好一件事"删除W合条g的属?
  • PROVIDERQ这是一个新的属性,它ƈ没有包含在JSON中,是ؓ(f)表示数据来源而新加的
  • SOQ这个就是前?div style="display: inline-block;">EvaluateJsonPath1解析出来的某个|那个元g无法直接加工Q所以放在这里做的二ơ加工,L前导0

    AttributesToJsonQ作用是一堆Attribute转换为JsonQ当然就只能是那U简单结构的JsonQ这里用它是ؓ(f)了配合后面一个Processor的?/span>
  • Attributes ListQ拿来生成JSON的属性列表,q里我其实把EvaluateJsonPath1、EvaluateJsonPath2和UpdateAttribute产生的属性都放上M (它们是我落地MariaDB的Table?
    • 不得不说的一个灰帔R憄l果Q那是生成的JSON属性顺序绝对不是你在List中写的属性顺序,我比较怀疑是在前面几个组件生成Attribute的顺序,但更让h遗憾的是它们的顺序也不会(x)是你l护它们的顺序。这个结果会(x)D我们在另外的Case 2中会(x)到一个不可逾越的障~~~~
  • Attributes Regular ExpressionQ符合条件的正则表达?/span>
  • DestinationQ?q个属性在 
    EvaluateJsonPath?/div>
    有Q?它可以让l果成ؓ(f)一个新的属性还是直接替换FlowFile的内容, Default是直接换掉FlowFile的内宏V?/div>

    ConvertJsonToSQLQ作用是Ҏ(gu)JSON内容转换成SQL语句以及(qing)语句所要的参数Q经q这一兛_FlowFile的内容就变成SQL语句Q然后Attribute中多Z些参?/span>

  • JDBC Connection PoolQConfigrue中指定的MariaDBq接字符Ԍ那里直接有指定Schema
  • Statement TypeQ?/em>q个有INSERT、UPDATE、DELETEq?个选项Q若是Mongo的那个组件就?x)看到有UPSERT(Update or Insert)Q其它各cȝ都木有~~~Q这里我使用的是INSERT选项Q后面通过玩的一点小花招把它再折腾ؓ(f)REPLACE INTO
  • Update KeysQ?q个属性可以不填,它是For Update时用的
    ?/div>
  • SQL Parameter Attribute PrefixQ?default = sqlQ它其实影响到组件处理后生成的SQL语句参数叫什么,设ؓ(f)sqlQ最后就?x)看到生成出?div style="display: inline-block;">。如下图是处理后的Attribute样式Q它?x)生sql.args.X.type和sql.args.X.valueQ这一l合h对应于SQL中第一?参数的类型及(qing)|”sql"是我们q里讄的前~名称 (充分考虑到大家会(x)惌搞事)

    ReplaceTextQ作用是文本替换Q这里就是我们处理Update Or Insert的关键,直接把SQL语句换掉?/span>
  • Search ValueQ在FlowFile中查扄字符Ԍ它支持正?/span>
  • Replacement ValueQ?/em>替换的|q里是单的把Insert Into (x1,x2,x3) values (?,?,?)处理为Replace Into (x1,x2,x3) values (?,?,?)而已QReplace Or Insert的行ZlDBd

    PutSQLQ作用是在DB上执行一DSQL语句
  • JDBC Connection PoolQ前面ConvertJsonToSQL转换SQL时就有用q,指定数据库的q接
  • SQL StatementQ?/em>需执行的SQLQؓ(f)I时表示使用前面传递过来的FlowFile的内?已经是一个SQL语句)


ȝQ?/h5>
    q是一个带有Key?多个Key?的无删除行ؓ(f)的资料接Ӟ所以可以利用AttributeToJSONd提取出来的有用属性重新生成JSON文gQƈ直接利用ConvertJsonToSQL转换为Insert语句?qing)对应的l定参数Q这里借用了MariaDB提供的Replace Into机制去自动用表上的Key键去做Update更新Q所以整个Nifi Flowq是比较单。在后箋文章中会(x)讲到带Delete行ؓ(f)的资料接收方法以?qing)无Key更新的解x?/span>


]]>
Oracle资料推送MQTThttp://www.tkk7.com/tw-ddm/articles/433709.html大大?/dc:creator>大大?/author>Wed, 10 Apr 2019 07:25:00 GMThttp://www.tkk7.com/tw-ddm/articles/433709.htmlhttp://www.tkk7.com/tw-ddm/comments/433709.htmlhttp://www.tkk7.com/tw-ddm/articles/433709.html#Feedback0http://www.tkk7.com/tw-ddm/comments/commentRss/433709.htmlhttp://www.tkk7.com/tw-ddm/services/trackbacks/433709.html需?/span>
资料从Oracle推至MQTTQ资料结果用JSON格式
场景1Q直接推?/span>
场景2Q仅当资料有变更时才推?/span>

解决Ҏ(gu)
QueryDatabaseTable --> ConvertAvroToJSON --> PublishMQTT


Processor?qing)其讑֮Q?/span>
QueryDatabaseTableQ?/span>作用是从DB中捞取资料,可以惌Nifi把它转成一个Select语句在执?/span>


  • Database Connection Pooling ServiceQ在Configure中设定的数据库连接,可以在Processor Group中被q
  • Database TypeQ这个设定的是Oracle。其实它与数据库q接讑֮有点重叠Q那边已l有指定是哪一U类型的DBQ这里需要再指定Q我想会(x)不会(x)是利用它来生成不同的Select查询语法?
  • Table NameQ表名,我这里用的是View名称QView其实已l对Table做出一些限定,可以挑选列?qing)设定查询条?/span>
  • Maximum-value ColumnsQ这个属性很重要Q如果不讑֮则Nifi在查询的时候会(x)捞取所有的资料Q如果有讑֮某个列,则Nifi仅会(x)捞取“?#8221;资料
    • 例如图上讑֮“BATCHID”q个列。第一ơNifi启动时捞取资料中最大BATCHID = 10Q则下一ơNifi再次启动时就只会(x)捞取BATCHID>10的资料,q且?x)自动记录下已经捞过的最大?/span>
    • 最大g存在下面q里QProcessor上右键选择“View State”


    • 下图可以看到当前最新的|?#8220;Clear State”则可以将保留值清I(Nifi下次启动时就?x)捞取所有资料)

  • 对于仅需要简单拉取资料的场景1来说Q?#8220;Maximum-value Columns”|空卛_Q而对于仅在资料有更新时才要拉取的场景2来说Q则需要设定ƈ且在View中做Z些调整才可以达成
    • 当有资料更新Ӟ则被更新资料的BatchID?x)是更新的|所以只要在View中虚拟BatchID?= Max(BatchID)Q就可以达成有资料更新才要拉取的效果
ConvertAvroToJSONQ将Avrocd资料转换为JSONQ这个可以不用改讑֮

PublishMQTTQ将资料Publish到MQTT指定Topic
  • Broker URIQ?/span>MQTT的Broker地址
  • Client IDQ?/span>发布MQTT的Client端IDQ注意不要多个Processor使用相同的Client IDQ这样ProcessorҎ(gu)被卡死)
  • TopicQ?/span>发布至MQTT的Topic名称
  • Retain MessageQ?/span>MQTT的遗a属性,x否保留推送的消息Q若设ؓ(f)falseQ则仅有当前q上MQTT的客L(fng)才能收到q笔消息Q?/span>



]]>
վ֩ģ壺 aëƬ߹ۿ| ZZIJZZIJձٸJIZJIZ | þҹҹ³³ƬӰ| AV뾫Ʒҹ.| ޸Ƶվ| ¾Ʒ޳a߹ۿ| Ƭ߹ۿ| 69˳鶹Ƶ| ԺȫƵƵ| ٶ˽ȫֱ| 2018av| ޾Ʒ߹ۿ| ޴߶ר| ޾Ʒ·һ߹ۿ| һƷһaһ| Ů18ëƬëƬѹۿ| þþþþóëƬѿ| ҹƬ| ŮһһˬƵ | ֳִˬƵ| Ѹ弤Ƶ| Ѹ弤| 18ŮëƬˮ| 91߹ۿ| þûɫվ| Ļavѷdvd| þùһƬѹۿ| xvideos| ѿһ߳ëƬ| ĻӰ߾Ʒ| 鶹ȫַ| һAëƬѹۿþþƷ | ɫһ| Ƶ| ̨һëƬ| й߹ۿѹ| ػaëƬƵ| ˽ӰԺƵվ| ѹۿһƬ| Ļѵַ߹ۿ| ߹ۿĻɫַ|