“歌唱北京”展首都新風貌_網頁設計公司

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

新時代的北京有新時代的歌曲,1月18日晚,原創音樂情景劇“歌唱北京”在中華世紀壇劇場上演,用情景劇、獨唱、合唱、舞蹈等形式展現新北京風貌。

2018年,北京廣播電視檯面向全球發起“歌唱北京”原創歌曲徵集活動,最終產生20首獲獎作品。2019年6月,“歌唱北京”原創歌曲徵集活動再次開啟。這次音樂情景劇中的歌曲就是“歌唱北京”征歌中的優秀作品。

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

情景劇以這三位年輕人的視角為切入點,男主角鄭能量是北京青年,女主角唱唱是海歸女孩,京京是一位海外華裔。三人在大興國際機場相遇,鄭能量和唱唱帶着京京領略新北京的風光,遊覽的過程融入了《北京樂章》《我們愛北京》《我愛的城市叫北京》《好客的北京》等歌曲。從前門的特色書店到大柵欄,從南鑼鼓巷到煙袋斜街,這些地標不僅出現在舞台背後的大屏幕上,也出現在“歌唱北京”的歌曲中。歌曲風格也十分多樣,有的有北京大鼓書的風韻,有的是快節奏的說唱,也有深受廣場舞愛好者喜歡的旋律。最終,三位年輕人被北京的高速發展震撼,決定一起為建設新時代的北京而奮鬥。

據悉,2019年度的“歌唱北京”征歌活動仍在進行中,主辦方希望更多市民加入描繪心中的北京,徵集時間將截至2020年3月30日。(記者 韓軒)

本站聲明:網站內容來http://www.societynews.cn/html/wh/fq/,如有侵權,請聯繫我們,我們將及時處理

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

HotRing: A Hotspot-Aware In-Memory Key-Value Store(FAST ’20)_貨運

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

  本文主要解決的是基於內存的K-V存儲引擎在實際應用中出現的熱點問題,設計了一個熱點可感知的KV存儲引擎,極大的提升了KV存儲引擎對於熱點數據訪問的承載能力。

Introduction

  熱點問題,可以理解為在一個嚴重傾斜的工作負載下,頻繁的訪問和操作某一小部分數據。

  如圖,是阿里的不同業務中數據訪問分佈情況,大量的數據訪問只集中在少部分的熱點數據中。在平常的情況下,百分之五十的用戶訪問請求只是針對其中百分之一的數據,在一些極端的情況下,當新產品發售後,大量的粉絲瘋狂進行搶購下單,業務的訪問量基本都聚集在某一小部分數據上,會出現百分之九十的用戶請求針對其中百分之一的數據。

   目前有一些方法來解決熱點數據問題:

  •      使用一致性哈希算法將數據分片,分佈到多個節點上,分攤熱點訪問。(Scale out using consistent hashing
  •      將熱點數據備份到多個節點上,分攤熱點訪問。 (Replication in multi-node
  •      客戶端緩存:通過預先標記熱點,設置客戶端層面的緩存。減小鍵值存儲系統的負載壓力。(Front-end cache

     第一種和第二種方法中因為節點的添加,會使得系統的成本會大大增加。第三種方法,如果用戶請求中涉及到很多數據更新的請求,對客戶端層面的緩存的數據需要維護,這個過程實現會變得很複雜。

 本篇論文則是從提升單個點對熱點數據的處理能力出發(Improve Single node’s ability to handle hotspots),設計了一種熱點可感知的鍵值數據結構,實現在嚴重傾斜的工作負載下,快速的完成用戶的訪問請求。

Prior work 

  現有很多基於內存的鍵值存儲引擎通常採用鏈式哈希作為索引,這種索引結構對熱數據是無法感應到,數據項被隨機的分佈在鏈表上。如果圖中item3是一個熱數據項,他處在某一鏈表的尾部,需要經過多次內存訪問才可以將item3的數據取出來。如果高度傾斜的工作負載下,要通過多次內存訪問才可以的得到item3,會使得系統的性能就會很低下。如果可以將熱點數據放置在衝突鏈頭部,那麼系統對於熱點數據的訪問將會有更快的響應速度。

 

Challenges 

  設計一個熱點可感知的索引結構需要解決兩個問題:

  • 數據的熱度是動態變化的,必須實現動態的熱點感知,保證熱點時效性。
  • 無鎖化處理,基於內存的鍵值存儲引擎性能是很敏感的,要保證高性能就必須支持無鎖的併發讀/寫操作

Design of HotRing   

  論文提出的索引結構被稱作hotring,與傳統的哈希結構不同的是,將哈希表中的鏈式結構改成了環,哈希表中存儲的頭指針可以指向環中的任意數據項。當鏈表變成環的時候,以頭指針所指的數據項為起點,查找要訪問的元素,如果元素不存在,就會一直循環查找下去,因此,作者將該還設計成一個有序環。

      在變成有序環的時候,因為表示key大小所用的字節數一般不會少(通常為10-100字節大小),只是簡單的對key進行排序,比較會帶來巨大的開銷。我們構建字典序:order = (tag, key)。先根據tag進行排序,tag相同再根據key進行排序:以itemB舉例,鏈式哈希需要遍歷所有數據才能返回read miss。而HotRing在訪問itemA與C后,即可確認B read miss。

Hotspot Shift Identification

  每段時間用戶的訪問需求在不斷變化,數據的熱度是動態變化的,HotRing實現了兩種策略來實現周期性的動態識別熱點並調整頭指針指向。

  1. 隨機移動策略
  2. 採樣分析策略

   隨機移動策略

   每個線程維護一個變量,記錄執行了多少次請求,每R次訪問,移動頭指針指向第R次訪問的數據項。若指針已經指向該數據項,則頭指針不移動。該策略的優勢是, 不需要額外的元數據開銷,實現簡單,響應速度快。

   缺點:

  • 若R小,找到熱點的時間會很短,但是可能造成頻繁的頭指針移動。
  • 若用戶的訪問負載傾斜程度小,頭指針移動的頻率會變高,效率就會降低。
  • 難以處理環中多個熱點數據。

  採樣分析策略

       使用該策略時,同樣的,在R次訪問后,若第R次訪問的item已經是頭指針指向的item,則不啟動採樣,否則,嘗試啟動對應衝突環的進行採樣。

在介紹採樣策略之前,先介紹一下頭指針和數據項對應的數據結構。頭指針head包括:

  • active:1 bit,作為控制採樣分析的標識。
  • total_counter:15 bits,當前環總共的訪問次數。
  • address:48 bits,環的頭地址(x86-64上目前只使用了48位)。

而環上每一項的next包括(因為現代操作系統所使用的內存地址空間使用64bit,而環中下一項的地址實際只需要48bit即可表示,其餘的16bit來控制併發,訪問次數等信息):

  • rehash:1 bit,作為控制rehash的標識。
  • occupied:1 bit,用於併發控制,保證併發訪問的正確性。
  • counter:14 bits,該項的訪問次數。
  • address:48 bits,下一項的地址。

  現在開始介紹採樣分析策略,如果第R次訪問數據項並不是頭指針指向的數據項,說明熱點數據已經發生了變化,這個時候會對衝突環進行採樣。採樣的過程如下:

  1. 打開head.active(CAS)
  2. 後續的請求的訪問記錄會被記錄到頭指針的total_count和對應item的的next.count(CAS)採樣個數也是R
  3. 採樣結束后,將頭指針的採樣標記恢復過來。

     CAS(Compare And Swap):當要操作內存中某一個變量的時候,會記錄下變量中的舊值,通過對舊值進行一系列的操作后得到新值,然後將舊值會與內存中的變量做比較,如果不相同,則說明內存中的值在這期間內被修改過,這時CAS操作將會失敗,新值將不會被寫入內存。如果相同,使內存中的變量變為新值。

     對數據採樣結束后,利用已有的信息可以進行判斷將哪一個數據項作為頭節點。具體過程如下:

  1. 遍歷環,計算每一項的訪問頻率。(第k項的訪問次數nk,環中所有項的訪問次數為N,則第k項的訪問頻率為nk/N)。
  2. 計算每個節點的收益W,取最小的收益的數據項作為新的熱數據項。每一項的受益值的計算公式如下,假設現在求第k項的收益,即計算所有項到該項的距離乘以該項的訪問頻率,求得每一項的期望值,選擇最小的期望值作為新的頭節點:

    3. 使用CAS原子操作將新的頭指針指向數據項。

    4. 重置頭指針和數據項的計數器。

 Write-Intensive Hotspot with RCU 

  在一般情況下,對於更新操作,HotRing可以對不超過8字節的數據進行update-in-place原子更新操作,這種情況下,讀取和更新被視作一樣的操作。但對於超過8個字節的大數據進行更新,hotring則會使用read-copy-update協議,RCU——更新數據的時候,首先拷貝一個副本,然後對副本進行修改,最後使用一個回調(callback)機制在適當的時機把指向原來數據的指針重新指向新的被修改的數據,這個期間數據都是可以隨意讀的。

  當更新的數據項是頭指針指向的熱數據項時,因為要修改前一個數據項的next指針,需要遍歷整個環來獲取頭節點的前一項。如圖,遍歷得到熱數據的前一項需要花費大量的內存訪問開銷。論文在這種情況下,更新的只是前一項的計數器,其他項的計數器不變,這樣可以使得頭指針可以在後面的策略調整中直接指向熱數據的前一項,使得對熱數據的更新需要的內存訪問操作就會減少。

 

 

Concurrent Operations

  1.Read操作

   Hotringd的讀取不需要任何的操作,操作完全無鎖。

  2.Insert操作

  當兩個線程都在B、D之間插入時,對原來結構的修改,只涉及到B項的next項,修改B項的next項的競爭衝突可以通過CAS保證線程安全。若前一項next字段發生競爭,CAS會失敗,此時操作需要重試。

 

3.Update操作

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

  當更新的數據不超過8字節:使用in-place update方法去更新即可,不需要其它操作,線程安全可以通過CAS保證。當更新的數據超過8字節:使用RCU更新,因為採用RCU方法,這時候需要分3種情況:

   ①RCU-update & Insert

  2個線程分別更新B和插入C,兩個線程對原來結構的影響分別是修改A的next指針和修改B的next指針,即便存在CAS操作,但兩者之間不存在衝突,所以兩個操作都會成功,但結果肯定不是我們所希望的。

 

 

   解決辦法:RCU-update前,嘗試CAS修改B.next值,置B.next.occupy = 1。另外一個線程的在完成插入操作時,使用CAS原子操作訪問前一個節點B的next字段,發現該字段的occupy位為1,操作會失敗,重試。操作完成后,新版本項的occupy為0。

  ②RCU-update & RCU-update

  2個線程分別更新B和更新D,兩個線程對原來結構的影響分別是修改A的next指針和修改B的next指針,即便存在CAS操作,但兩者之間不存在衝突,所以兩個操作都會成功,但結果肯定不是我們所希望的。

   解決辦法:更新B的時候,創建一個新的數據項B’,使用CAS操作修改B的,置B.next.occupy = 1,當另一個線程修改D節點后,使用CAS連接前一個節點B的時候,發現B.next.occupy = 1,操作會失敗,重試。

  ③RCU-update & Delete 

  2個線程分別刪除B和更新D,會出現和上述一樣的問題。此處不再贅述。

 4.頭指針在併發下的移動操作

  • 當要移動頭指針時,為了避免新的頭節點在這個過程中出現更新或者刪除的情況,導致頭指針可能指向無效的數據項,我們會通過CAS設置新的頭節點的occupy為1,保證不被被其他操作更新/刪除。
  • 當頭節點被更新時:更新時會設置新版本的頭節點occupy為1,使得其他操作無法對新節點造成影響。將頭指針指向新的頭節點,將新版本的occupy標記為0
  • 當頭節點被刪除時:除了設置當前被刪除的頭節點occupy為1,還得設置下一項的occupy為1,因為下一項是新的頭節點,需要保證其不被更新/刪除

 Lock-free Rehash

     當衝突環上存在多個熱點數據時,鍵值對存儲引擎的性能就會大大降低。因此HotRing設計了無鎖rehash策略來解決這一問題。和普通的哈希表不同的是使用負載因子來觸發rehash不同,HotRing使用訪問開銷(即操作平均內存訪問次數)來觸發rehash,文中設置平均內存訪問次數超過2的時候,就會自動觸發。HotRing rehash分為3步:

  1. 初始化 ——首先創建線程來專門處理rehash操作,初始化一個2倍大小的散列表,復用tag的最高一位來進行索引,將原先的一個環拆分成了兩個環。根據tag範圍對數據項進行劃分。假設tag最大值為T,tag範圍為[0,T),則兩個新的頭指針對應tag範圍為[0,T/2)和[T/2,T)。然後該線程創建一個rehash node,裡面包含2個rehash child item,作為2個新環的頭,它的格式和data item一樣,但是tag值分別是0和T/2。

                                                                                               

  2. 分割——接下來需要分割原有的環到2個新的環。如圖,因為itemB和E是tag的範圍邊界,所以線程會將兩個rehash item節點分別插入到itemB和E之前。到目前為止,已經在邏輯上將衝突環一分為二。

 

 

 

 

  3. 刪除——最後一步,將每一個環中首尾兩部分連接在一起。此外,還有一些收尾工作,包括舊哈希表的回收、以及rehash節點的刪除回收等。需要注意的是,在完成刪除操作之前,要確保所有對舊哈希表的訪問已經結束。只有rehash線程會阻塞一段時間。

 

 Evaluation

Experimental Setting

  在一台內存容量為32GB的服務器上測試的,測試的時候使用YCSB提供5種工作負載,默認情況下,使用64個線程在兩億五千萬個鍵值對測試負載B,在測試負載中,有百分之97.8的操作是針對其中百分只1的數據,百分之99.8的操作是針對10%的數據,

Deployment

  •   HotRing-r (random movement strategy)
  •   HotRing-s (sampling statistics strategy)

Baselines

  • Chaining Hash(a lock-free chain-based hash index that is modified from the hash structure in Memcached.)
  • FASTER(SIGMOD 2019)
  • Masstree
  • Memcached

在單線程和多線程情況下,對這幾種數據結構的性能進行了測試。Hotring在大量讀操作的情況下,可以實現一個很高的性能。

  下圖中,左圖表明,鏈或者環中數據項的個數即便很多,hotring也可以保持一個很好的性能。右圖表明hotring在數據訪問呈現嚴重傾斜的情況下,也能保持非常好的性能。(θ是齊夫分佈的參數,YCSB生成工作負載時, θ的值越高,表明測試的所使用負載的傾斜程度就越嚴重。)

   在下圖中,左圖表明hotring在read miss的情況下的性能比chaining hash的性能要好。這是因為hotring中每一個桶的環是有序的,判斷元素不存在不需要遍歷桶中的所有元素。右圖熱點切換時,不同的熱點選擇策略穩定下來需要的時間,hotring-r在兩秒內就可以達到一種穩定的狀態了。

   在分裂前,為了保證從舊哈希表進入的訪問均已經返回,rehash的過程被阻塞一段時間,隨着數據容量的不斷增長,rehash操作可以維持這個穩定的性能。如下圖所示:

 

參考資料:

1.Jiqiang Chen, Liang Chen, Sheng Wang, Guoyun Zhu, Yuanyuan Sun, Huan Liu, Feifei Li:HotRing: A Hotspot-Aware In-Memory Key-Value Store. FAST 2020: 239-252

2. 最快KV引擎!存儲頂會FAST’20論文揭秘Tair創新性引擎

3.Presentation Video 

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

RabbitMQ 高級應用_網頁設計公司

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

 

 

本文是作者原創,版權歸作者所有.若要轉載,請註明出處.

本文RabbitMQ版本為rabbitmq-server-3.7.17,erlang為erlang-22.0.7.請各位去官網查看版本匹配和下載,也可以留言,我發安裝包

 

過期時間TTL(Time To Live)

過期時間TTL表示可以對消息設置預期的時間,在這個時間內都可以被消費者接收穫取;過了之後消息將自動被刪除。RabbitMQ可以對消息和隊列設置TTL。目前有兩種方法可以設置。

  • 第一種方法是通過隊列屬性設置,隊列中所有消息都有相同的過期時間。
  • 第二種方法是對消息進行單獨設置,每條消息TTL可以不同。

如果上述兩種方法同時使用,則消息的過期時間以兩者之間TTL較小的那個數值為準。消息在隊列的生存時間一旦超過設置的TTL值,就稱為dead message被投遞到死信隊列, 消費者將無法再收到該消息。

1. 設置隊列TTL

配置resources\spring\spring-rabbitmq.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">

    <!--定義過期隊列及其屬性,不存在則自動創建-->
    <rabbit:queue id="my_ttl_queue" name="my_ttl_queue" auto-declare="true">
        <rabbit:queue-arguments>
            <!--投遞到該隊列的消息如果沒有消費都將在6秒之後被刪除-->
            <entry key="x-message-ttl" value-type="long" value="6000"/>
        </rabbit:queue-arguments>
    </rabbit:queue>
<rabbit:connection-factory id="connectionFactory" host="192.168.75.163"
port="5672"
username="test01"
password="test01"
virtual-host="/hello"

/>
</beans>

參數 x-message-ttl 的值 必須是非負 32 位整數 (0 <= n <= 2^32-1) ,以毫秒為單位表示 TTL 的值。這樣,值 6000 表示存在於 隊列 中的當前 消息 將最多只存活 6 秒鐘

如果不設置TTL,則表示此消息不會過期。如果將TTL設置為0,則表示除非此時可以直接將消息投遞到消費者,否則該消息會被立即丟棄。

 

然後在測試類中編寫如下方法發送消息到上述定義的隊列:

@RunWith(SpringRunner.class)
@SpringBootTest
public class ProducerTest {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 過期隊列消息
     * 投遞到該隊列的消息如果沒有消費都將在6秒之後被刪除
     */
    @Test
    public void ttlQueueTest(){
        //路由鍵與隊列同名
        rabbitTemplate.convertAndSend("my_ttl_queue", "發送到過期隊列my_ttl_queue,6秒內不消費則不能再被消費。");
    }

}

啟動類中導入配置文件

//導入配置文件
@ImportResource("classpath:/spring/spring-rabbitmq.xml")
@SpringBootApplication
public class ProducerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProducerApplication.class, args);
    }

}

執行單元測試,看結果

 

 

 6秒后,再看結果

 

 

 

2. 設置消息TTL

消息的過期時間;只需要在發送消息(可以發送到任何隊列,不管該隊列是否屬於某個交換機)的時候設置過期時間即可。

在測試類中編寫如下方法發送消息並設置過期時間到隊列:

/**
     * 過期消息
     * 該消息投遞任何交換機或隊列中的時候;如果到了過期時間則將從該隊列中刪除
     */
    @Test
    public void ttlMessageTest(){
        MessageProperties messageProperties = new MessageProperties();
        //設置消息的過期時間,3秒
        messageProperties.setExpiration("3000");
        Message message = new Message("測試過期消息,3秒鐘過期".getBytes(), messageProperties);
        //路由鍵與隊列同名
        rabbitTemplate.convertAndSend("my_ttl_queue", message);
    }

expiration 字段以微秒為單位表示 TTL 值。且與 x-message-ttl 具有相同的約束條件。因為 expiration 字段必須為字符串類型,broker 將只會接受以字符串形式表達的数字。

當同時指定了 queue 和 message 的 TTL 值,則兩者中較小的那個才會起作用。

 

死信隊列

DLX,全稱為Dead-Letter-Exchange , 可以稱之為死信交換機,也有人稱之為死信郵箱。

當消息在一個隊列中變成死信(dead message)之後,它能被重新發送到另一個交換機中,這個交換機就是DLX ,綁定DLX的隊列就稱之為死信隊列。

消息變成死信,可能是由於以下的原因:

  • 消息被拒絕
  • 消息過期
  • 隊列達到最大長度

DLX也是一個正常的交換機,和一般的交換機沒有區別,它能在任何的隊列上被指定,實際上就是設置某一個隊列的屬性。

當這個隊列中存在死信時,Rabbitmq就會自動地將這個消息重新發布到設置的DLX上去,進而被路由到另一個隊列,即死信隊列。

要想使用死信隊列,只需要在定義隊列的時候設置隊列參數 x-dead-letter-exchange 指定交換機即可。

 

 

具體步驟如下

1. 定義死信交換機

<!--定義定向交換機中的持久化死信隊列,不存在則自動創建-->
<rabbit:queue id="my_dlx_queue" name="my_dlx_queue" auto-declare="true"/>

<!--定義廣播類型交換機;並綁定上述隊列-->
<rabbit:direct-exchange id="my_dlx_exchange" name="my_dlx_exchange" auto-declare="true">
<rabbit:bindings>
<!--綁定路由鍵my_ttl_dlx、my_max_dlx,可以將過期的消息轉移到my_dlx_queue隊列-->
<rabbit:binding key="my_ttl_dlx" queue="my_dlx_queue"/>
<rabbit:binding key="my_max_dlx" queue="my_dlx_queue"/>
</rabbit:bindings>
</rabbit:direct-exchange>

2. 隊列設置死信交換機

<!--定義過期隊列及其屬性,不存在則自動創建-->
<rabbit:queue id="my_ttl_dlx_queue" name="my_ttl_dlx_queue" auto-declare="true">
<rabbit:queue-arguments>
<!--投遞到該隊列的消息如果沒有消費都將在6秒之後被投遞到死信交換機-->
<entry key="x-message-ttl" value-type="long" value="6000"/>
<!--設置當消息過期后投遞到對應的死信交換機-->
<entry key="x-dead-letter-exchange" value="my_dlx_exchange"/>
</rabbit:queue-arguments>
</rabbit:queue>

<!--定義限制長度的隊列及其屬性,不存在則自動創建-->
<rabbit:queue id="my_max_dlx_queue" name="my_max_dlx_queue" auto-declare="true">
<rabbit:queue-arguments>
<!--投遞到該隊列的消息最多2個消息,如果超過則最早的消息被刪除投遞到死信交換機-->
<entry key="x-max-length" value-type="long" value="2"/>
<!--設置當消息過期后投遞到對應的死信交換機-->
<entry key="x-dead-letter-exchange" value="my_dlx_exchange"/>
</rabbit:queue-arguments>
</rabbit:queue>

<!--定義定向交換機 根據不同的路由key投遞消息-->
<rabbit:direct-exchange id="my_normal_exchange" name="my_normal_exchange" auto-declare="true">
<rabbit:bindings>
<rabbit:binding key="my_ttl_dlx" queue="my_ttl_dlx_queue"/>
<rabbit:binding key="my_max_dlx" queue="my_max_dlx_queue"/>
</rabbit:bindings>
</rabbit:direct-exchange>

3. 消息過期的死信隊列測試

/**
     * 過期消息投遞到死信隊列
     * 投遞到一個正常的隊列,但是該隊列有設置過期時間,到過期時間之後消息會被投遞到死信交換機(隊列)
     */
    @Test
    public void dlxTTLMessageTest(){
        rabbitTemplate.convertAndSend(
                "my_normal_exchange",
                "my_ttl_dlx",
                "測試過期消息;6秒過期後會被投遞到死信交換機2222");
    }

運行看結果

 

 6秒后

 

 

4. 消息溢出的死信隊列測試

/**
     * 消息長度超過2,會投遞到死信隊列中
     */
    @Test
    public void dlxMaxMessageTest(){
        rabbitTemplate.convertAndSend(
                "my_normal_exchange",
                "my_max_dlx",
                "發送消息4:消息長度超過2,會被投遞到死信隊列中!");

        rabbitTemplate.convertAndSend(
                "my_normal_exchange",
                "my_max_dlx",
                "發送消息5:消息長度超過2,會被投遞到死信隊列中!");

        rabbitTemplate.convertAndSend(
                "my_normal_exchange",
                "my_max_dlx",
                "發送消息6:消息長度超過2,會被投遞到死信隊列中!");
        
    }

運行,看結果

 

 

 

 上面發送的3條消息中的第1條消息會被投遞到死信隊列中

 

延遲隊列

延遲隊列存儲的對象是對應的延遲消息;所謂“延遲消息” 是指當消息被發送以後,並不想讓消費者立刻拿到消息,而是等待特定時間后,消費者才能拿到這個消息進行消費。

在RabbitMQ中延遲隊列可以通過 過期時間 + 死信隊列 來實現

 

 

延遲隊列的應用場景;如:

  • 在電商項目中的支付場景;如果在用戶下單之後的幾十分鐘內沒有支付成功;那麼這個支付的訂單算是支付失敗,要進行支付失敗的異常處理(將庫存加回去),這時候可以通過使用延遲隊列來處理
  • 在系統中如有需要在指定的某個時間之後執行的任務都可以通過延遲隊列處理

具體代碼不演示了

 

消息確認機制

確認並且保證消息被送達,提供了兩種方式:發布確認和事務。(兩者不可同時使用)在channel為事務時,不可引入確認模式;同樣channel為確認模式下,不可使用事務。

1 發布確認

消息發送成功確認

connectionFactory 中啟用消息確認:

<rabbit:connection-factory id="connectionFactory" host="192.168.75.163"
                               port="5672"
                               username="test01"
                               password="test01"
                               virtual-host="/hello"
                               publisher-confirms="true"
    />

配置消息確認回調方法如下:

<!-- 消息回調處理類 -->
<bean id="confirmCallback" class="com.itheima.rabbitmq.MsgSendConfirmCallBack"/>
<!--定義rabbitTemplate對象操作可以在代碼中方便發送消息-->
<!-- confirm-callback="confirmCallback" 表示:消息失敗回調 -->
<rabbit:template id="rabbitTemplate" connection-factory="connectionFactory" 
        confirm-callback="confirmCallback"/>

消息確認回調方法如下:

public class MsgSendConfirmCallBack implements RabbitTemplate.ConfirmCallback {
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack) {
            System.out.println("消息確認成功....");
        } else {
            //處理丟失的消息
            System.out.println("消息確認失敗," + cause);
        }
    }
}

我們手動建一個spring_queue隊列.並測試如下:

 @Test
    public void queueTest(){
        //路由鍵與隊列同名
        rabbitTemplate.convertAndSend("spring_queue", "只發隊列spring_queue的消息。");
    }

查看結果

 

 

 

 消息發送失敗回調

connectionFactory 中啟用回調:

!-- publisher-returns="true" 表示:啟用了失敗回調 -->
<rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}"
        port="${rabbitmq.port}"
        username="${rabbitmq.username}"
        password="${rabbitmq.password}"
        virtual-host="${rabbitmq.virtual-host}"
        publisher-returns="true" />

配置消息失敗回調方法如下:

<!-- 消息失敗回調類 -->
<bean id="sendReturnCallback" class="com.itheima.rabbitmq.MsgSendReturnCallback"/>
<!-- return-callback="sendReturnCallback" 表示:消息失敗回調 ,同時需配置mandatory="true",否則消息則丟失-->
<rabbit:template id="rabbitTemplate" connection-factory="connectionFactory"
        confirm-callback="confirmCallback" return-callback="sendReturnCallback" 
        mandatory="true"/>

注意:同時需配置mandatory=”true”,否則消息則丟失

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

 

消息失敗回調方法如下:

public class MsgSendReturnCallback implements RabbitTemplate.ReturnCallback {
    public void returnedMessage(Message message, int i, String s, String s1, String s2) {
        String msgJson  = new String(message.getBody());
        System.out.println("Returned Message:"+msgJson);
    }
}

模擬消息發送失敗,功能測試如下:

@Test
public void testFailQueueTest() throws InterruptedException {
    //exchange 正確,queue 錯誤 ,confirm被回調, ack=true; return被回調 replyText:NO_ROUTE
    amqpTemplate.convertAndSend("test_fail_exchange", "", "測試消息發送失敗進行確認應答。");
}

失敗回調結果如下:

 

 

事務支持

場景:業務處理伴隨消息的發送,業務處理失敗(事務回滾)后要求消息不發送。rabbitmq 使用調用者的外部事務,通常是首選,因為它是非侵入性的(低耦合)。

外部事務的配置

<rabbit:template id="rabbitTemplate"
                     connection-factory="connectionFactory"

                     mandatory="true"
                     channel-transacted="true"
    />

    <!--平台事務管理器-->
    <bean id="transactionManager" class="org.springframework.amqp.rabbit.transaction.RabbitTransactionManager">
        <property name="connectionFactory" ref="connectionFactory"/>
    </bean>

測試類或者測試方法上加入@Transactional註解

   @Test
    @Transactional //開啟事務
    //@Rollback(false)//在測試的時候,需要手動的方式制定回滾的策略
    public void queueTest2(){
        //路由鍵與隊列同名
        rabbitTemplate.convertAndSend("spring_queue", "只發隊列spring_queue的消息--02222222222222222222。");
        System.out.println("----------------dosoming:可以是數據庫的操作,也可以是其他業務類型的操作---------------");
        //模擬業務處理失敗
        //System.out.println(1/0);
        rabbitTemplate.convertAndSend("spring_queue", "只發隊列spring_queue的消息--02。");
    }

運行看結果

 

 

 

 

 

 因為是測試類,所以spring自動回滾了,需要我們手動禁止回滾

   @Test
    @Transactional //開啟事務
    @Rollback(false)//在測試的時候,需要手動的方式制定回滾的策略
    public void queueTest2(){
        //路由鍵與隊列同名
        rabbitTemplate.convertAndSend("spring_queue", "只發隊列spring_queue的消息--02222222222222222222。");
        System.out.println("----------------dosoming:可以是數據庫的操作,也可以是其他業務類型的操作---------------");
        //模擬業務處理失敗
        //System.out.println(1/0);
        rabbitTemplate.convertAndSend("spring_queue", "只發隊列spring_queue的消息--02。");
    }

再執行一次測試類,查看結果

 

 

 我們手動弄個異常,再試一次

  @Test
    @Transactional //開啟事務
    @Rollback(false)//在測試的時候,需要手動的方式制定回滾的策略
    public void queueTest2(){
        //路由鍵與隊列同名
        rabbitTemplate.convertAndSend("spring_queue", "只發隊列spring_queue的消息--02222222222222222222。");
        System.out.println("----------------dosoming:可以是數據庫的操作,也可以是其他業務類型的操作---------------");
        //模擬業務處理失敗
        System.out.println(1/0);
        rabbitTemplate.convertAndSend("spring_queue", "只發隊列spring_queue的消息--02。");
    }

看結果

 

 

 這裏4條是因為我手動禁止了回滾

結果應該是沒問題的,就不測試了

 

消息追蹤

1.消息追蹤啟用與查看

消息中心的消息追蹤需要使用Trace實現,Trace是Rabbitmq用於記錄每一次發送的消息,方便使用Rabbitmq的開發者調試、排錯。可通過插件形式提供可視化界面。

Trace啟動後會自動創建系統Exchange:amq.rabbitmq.trace ,每個隊列會自動綁定該Exchange,綁定后發送到隊列的消息都會記錄到Trace日誌。

 

查看插件列表

rabbitmq-plugins list

 

 

 

 

rabbitmq啟用trace插件

rabbitmq-plugins enable rabbitmq_tracing

命令集 描述
rabbitmq-plugins list 查看插件列表
rabbitmq-plugins enable rabbitmq_tracing rabbitmq啟用trace插件
rabbitmqctl trace_on 打開trace的開關
rabbitmqctl trace_on -p test01 打開trace的開關(itcast為需要日誌追蹤的vhost)
rabbitmqctl trace_off 關閉trace的開關
rabbitmq-plugins disable rabbitmq_tracing rabbitmq關閉Trace插件
rabbitmqctl set_user_tags test01 administrator 只有administrator的角色才能查看日誌界面

 

 

 

 

 

 

 

 

 

 

 安裝插件並開啟 trace_on 之後,會發現多個 exchange:amq.rabbitmq.trace ,類型為:topic。

 

 

2 日誌追蹤

首先重新登錄管理控制台

 

 

第一步:發送消息

@Test
    public void queueTest3() throws InterruptedException {
        rabbitTemplate.convertAndSend("spring_queue", "只發隊列spring_queue的消息--01。");
    }

 

 第二步:查看trace

第三步:點擊Tracing查看Trace log files

 

 

第四步:點擊itest-log.log確認消息軌跡正確性

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

這款2.0L全新SUV氣場堪比寶馬X6!上市后13萬內就賣瘋_包裝設計

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

上新台中搬家公司提供您一套專業有效率且人性化的辦公室搬遷、公司行號搬家及工廠遷廠的搬家服務

不過遺憾的是T90並沒有配備群眾們喜聞樂見的全景天窗,只是尺寸也不算很大的普通天窗。乘坐空間這一點對於國內消費者來說就是重中之重了,國人就是喜歡大尺寸、大空間,畢竟拖家帶口空間小了坐着確實憋屈。T90的座椅使用了和天籟同級的人體工程學座椅,座椅填充物柔軟,舒適性和包裹性都非常好,絕對也能稱得上是移動大沙發。

前段時間小編去體驗了一把國產版寶馬X6-啟辰T90,之所以說是X6,是因為在外形上,T90和X6看起來確實比較像。T90定位中型轎跑型SUV,上市之後將會成為啟辰的旗艦車型。預售價將會在廣州車展上公布。

由於是中型SUV,所以T90的尺寸自然不會小,長寬高為4793*1865*1592mm,軸距為2765mm,個頭算是挺大的了。因為是溜背的造型,再加上較長的車身,所以側面來看T90顯得很修長,同時空載的時候最小離地間隙為194mm,通過性還是不錯的。不過最吸引人的是廠家宣稱T90是啟辰“風雕美學”設計理念的第一款車型,整車原創度非常高,同時別緻的前進氣格柵也使T90讓人眼前一亮。

到了車內,大家會發現T90的原創度會更高了,內飾不管是做工還是用料,都是十分的用心。新車的氣味較小,可見內飾選材還是比較嚴格的。同時配置又很高,尤其是中控那個高達12.3英寸的大屏幕,絕對很奪人眼球,同時它的分辨率高達1920*768,畫面清晰,運行流暢,

※產品缺大量曝光嗎?你需要的是一流包裝設計!

窩窩觸角包含自媒體、自有平台及其他國家營銷業務等,多角化經營並具有國際觀的永續理念。

沒有遇到卡頓的情況。同時它還可以分屏显示,左側小屏幕显示菜單功能,不會影響右側屏幕的显示。配備百度CarLife系統,這是啟辰和百度合作開發的,可以鏈接安卓和蘋果手機,功能豐富。

不單中控做的好,內飾用料也很不錯。進入車內凡是手可以碰到的地方全部是使用了軟性材料,比如中控面板,扶手箱,門把手等,所以幾乎你在車內是感覺不到廉價感覺的。不過遺憾的是T90並沒有配備群眾們喜聞樂見的全景天窗,只是尺寸也不算很大的普通天窗。

乘坐空間這一點對於國內消費者來說就是重中之重了,國人就是喜歡大尺寸、大空間,畢竟拖家帶口空間小了坐着確實憋屈。T90的座椅使用了和天籟同級的人體工程學座椅,座椅填充物柔軟,舒適性和包裹性都非常好,絕對也能稱得上是移動大沙發。後排空間較大,但是溜背的造型會犧牲一定的頭部空間。

動力系統應該是T90最拿得出手的東西了。T90配備日產MR20自然吸氣發動機,排量為2.0L,最大功率144馬力,最大扭矩198牛·米,匹配CVT無級變速箱。這套動力系統同時也在天籟和逍客上面使用,所以T90的動力系統應該是很讓人放心了。畢竟這是一套成熟、可靠、穩定、經濟的動力系統。

T90馬上就會成為啟辰的旗艦轎車,所以啟辰方面也是特別重視的,從整車的做工來看也能看出來廠家確實是在用心做產品。後期我們還會有T90的試駕文章,喜歡它的消費者可以留意一下。

儘管T90會在即將到來的廣州車展公布預售價,但是官方曾說,這款車的預售價在20萬以下,聽到這價格我就心涼了半截,只是覺得,好貴…到時候價格真的是接近20萬了,那估計銷量真的堪比寶馬X6了。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網動廣告出品的網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上她。

古堡里的中國年_貨運

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

  皇城相府內的民俗表演。
  資料圖片

  冬雪至,年味濃。位於山西省晉城市的皇城相府中,雪花從紫雲山前山河樓旁飄下,落在這座有600年歷史的明清古堡。

  皇城相府是沁河流域數千座古堡之一。明末清初,沁河流域修建起大大小小的城堡,城牆、護城河、瞭望樓、磨坊、水井一應俱全,更以內外雙城聞名於世。這裡有大型院落16座,房屋640餘間。御書樓金碧輝煌,中道庄巍峨壯觀,斗築居府院連綿,河山樓雄偉險峻,是一處罕見的明清城堡式住宅建築群,雖經歷代戰火,仍保存完好。

  明崇禎六年,陳廷敬伯父陳昌言為避戰亂始建皇城相府的內城“斗築居”。清康熙年間,陳廷敬又修建了外城。康熙皇帝曾兩次來到皇城相府,且御筆親書“午亭山村”,成為一塊金字招牌。

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

  2020年新春,皇城相府特別推出“玩文化‘潮’年,‘趣’皇城相府”主題系列新春廟會。融合創意互動、線上打卡、線下體驗、非遺表演、非遺市集、特色美食、花車巡遊等精彩內容,奉上一場精彩絕倫的文化大餐。

  春節期間,在皇城相府走走,你可以真真切切地觸摸歷史。

  行走在古樸厚重的街巷,掀開珠簾,跨步入室,你會不禁感嘆歷史在這裏靜止;夜宿郭峪古城,每晚的打鐵花表演會擦亮古城的夜空;逛逛廟會,你可以走進非遺文化展,近距離欣賞本土和網紅非遺文化;跟着“花車巡遊”,你可以快速地融入到這一片歡樂祥和的年節氛圍中;除了遊客熟悉的表演外,浸入式、行進式的實景劇《再回相府》再次登場,帶你了解一代名相陳廷敬的故事。

  有文化、有故事,皇城相府帶你過個熱鬧的中國年。

本站聲明:網站內容來http://www.societynews.cn/html/wh/fq/,如有侵權,請聯繫我們,我們將及時處理

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

剪窗花過年_網頁設計公司

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

  圖為中國剪紙。
  劉建華攝(影像中國)

  圖為北京前門大街的迎春燈籠。
  郭俊鋒攝(影像中國)

  過春節,一般年前最忙。到大年初一,人們就可以盡享清福,闔家歡樂了。年前,男主人、女主人都要外出忙着採購年貨,一些婦女和孩子留在家裡,洒掃庭除之後,圍坐在炕頭和桌前,開始剪窗花了。

  這樣的風俗,有兩方面原因。

  一是,剪出的窗花貼到窗上,和大門兩旁貼的春聯、大門中央貼的門神、屋子牆上貼的福字,和房檐門楣上掛的吊錢,一定都要在大年三十之前完成,才算是過年的樣子。清末竹枝詞里說:“掃室糊棚舊換新,家家戶戶貼宜春。”其中的“貼”字說的就是準備過年這樣必需的程式。

  另一面,和過年的時候家裡人不許動刀剪的民俗有關(還有不許掃地倒臟土等,都是防止不吉利的說法)。清時詩人查慎行有詩:“巧裁幡勝試新羅,畫彩描金作鬧蛾。從此刀剪閑一月,閨中針線歲前多。”這裏說的巧裁新羅,畫彩描金,就包含有剪窗花,從此刀剪閑一月,後來改成到正月十五;再後來到破五;現在,已經徹底沒有這個風俗了。

  春聯、門神、福字、窗花和吊錢,這五項過年之前之必備,我稱之為過年五件套。和後來結婚時候一度流行的手錶、自行車和大衣櫃這三件套的說法相類似。只是,結婚三件套,早已被時代的發展所淘汰,而過年這五件套,幾百年過去了,至今依然風俗變化不大,除了吊錢如今在北京見到的少了,其餘四種,仍然在過年前看許多人家在忙乎張羅。因為這是過年必備的慶祝儀式的硬件標準。可見,民俗的力量,在潛移默化中,代代傳承。

  到正月十五燈節之前,再加上各家大門前掛上一盞紅燈籠,就是過年必備的六件套。這六件套,全部都是紅顏色,過年前後這一段時間里,全國各地,無論鄉間,還是城市,到處是這樣一片中國紅,那才叫過年,是過年的色彩。如果說過年到處是這樣紅彤彤一片的海洋翻滾,那麼,窗花是其中奪目的浪花簇擁。

  過去的歲月里,年前要準備的這五件套,除了門神尉遲恭秦叔寶的形象複雜,要到外面買那種木刻現成的之外,其餘四件,普通百姓人家,都是要自己動手做的。這和年三十晚上的那頓餃子必須得全家動手包一樣,參与在過年的程式之中,才像是過年的樣子。普通人家剪窗花,是和貼春聯、掛吊錢,包括做門神、寫福字一樣,都只用普通的大紅紙。各家都須到紙店裡買大紅紙。大紅紙暢銷得很。

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

  那時候,家附近有兩家老字號的紙店,一家是南紙店,叫公興號,在大柵欄東口路南;一家是京紙店,叫敬庄號,在興隆街,我們大院後身。家裡人一般都將這項任務交給我們小孩子,我們都願意舍近求遠去公興號,一是那裡店大,紙的品種多;二來路過前門大街,到處是賣各種小吃的店鋪和攤子,我們可以將買紙剩下的錢買點兒吃的解饞。家裡人都囑咐我們買那種便宜的大紅紙。其實,不用囑咐,我們都會買最便宜的,這樣剩下的錢會多點兒,買的吃食也會多點兒呢。

  有一陣子,公興號流行賣一種電光紙,我們又叫它玻璃紙,因為它像玻璃一樣反光,一閃一閃。我們都喜歡,便買回家。家裡大人不樂意,看着就撇嘴,讓我們立馬兒拿回去換紙,一準覺得還是傳統的那種大紅紙好。

  過去年月里普通人家房子的紙窗,貼的都是高粱紙,很薄,透光性好。傳統的大紅紙也很薄,做成窗花,貼在這樣的花格紙窗上,很是四襯適合。清末《燕都雜詠》有一首說:“油花窗紙換,掃舍又新年。戶寫宜春字,囊分壓歲錢。”詩後有注:“紙繪人物,油之,剪貼窗上,名‘窗花’。”詩中所說的油花窗紙,指的應該就是這種高粱紙,紅紅的窗花貼在上面,紅白相映,屋裡屋外,看着都透亮,紅艷艷的,顯得很喜興。電光紙厚,貼在這樣的花格紙窗上,不僅不透亮,還反光,沒有那種裡外通透的感覺。確實是什麼衣配什麼人,什麼鞍配什麼馬,傳統的窗花用紙,和老式的紙窗兩兩相宜。老祖宗傳下來的玩意兒,有它的道理。

  後來,經濟條件好些了,各家的窗子換成玻璃的,還是覺得貼這種傳統大紅紙剪成的窗花好看。那種電光紙,到底沒能剪成窗花,亮相在我們的窗戶上。

  窗花,是老祖宗傳下來的,既是手藝,也是民俗;既可以是結婚時的裝點,更形成了過年必不可少的一項內容。窗花的歷史悠久,有人說自漢代發明了紙張之後就有了窗花,這我不大相信,紙張剛剛出現的時候,應該很貴,不可能普遍用於窗花。有人說南北朝時對馬團花和對猴團花中就有了鋸齒法和月牙法等古老的剪紙法;有人說唐朝就有,有李商隱的詩為證:“鏤金作勝傳荊俗,剪綵為人起晉風”;也有人說窗花流行於宋元之後……總之,窗花的歷史悠久。

  我私下猜想,窗花最初是用刀刻,然後轉化為剪裁。刀刻出的圖案,應該受到過更早時的石刻或青銅器的雕刻影響,藝術總是相通的,相互影響和借鑒是存在的。從石刻到剪紙,從刀到剪,只是工具和材料的變化而已。剪和刻的區別,還在於剪是要把紙先折成幾疊,是在石頭上無法做到的。別看只是這樣看似簡單的幾疊,卻像變魔術一樣,讓剪紙變成了獨特的藝術。

  窗花,應該是剪紙的前身。窗花也好,剪紙也好,不像石刻或青銅器雕刻,多在王公貴族那邊,而是更多在民間,其民間的元素更多更濃。窗花,又是農耕時代的產物,所以,它的內容更多的是花草魚蟲、飛禽走獸、農事稼穡、民間傳說、神話人物,以至後來還有八仙過海、五福捧壽等很多戲劇內容,可以說是花樣繁多,應有盡有。只有正月十五燈節時的彩燈上描繪的內容,可以和窗花有一拼。燈上的圖案,在窗花上大多可以一一找到對應,只不過,在窗花上刪繁就簡,都變成大紅紙一色的紅。這便是窗花獨到之處,一色的紅,配窗子一色的白,如果過年期間趕上一場大雪,紅白對比得格外強烈,就更漂亮了。

  民間藏龍卧虎,窗花有簡有繁。有的很豐富,我從來沒有見過。前面所引的《燕都雜詠》詩后還有一注,說有這樣的窗花,是“或以陽起石揭薄片,繪花為之”。這種類似拓印式的窗花,我沒見過。《帝京風物略》中說:“門窗貼紅紙葫蘆,曰收瘟鬼。”這風俗和年三十之夜踩松柏枝謂之驅鬼的意思是一樣的。大年三十的夜晚,踩松柏枝,我沒有踩過,那時我們院子里有人買來秫秸稈,讓我們小孩子踩,意思是一樣的。但是,這種貼紅紙葫蘆的窗花,我也沒見過。《燕京雜記》中說:“剪紙不斷,供於祖前,謂之‘阡張’。”過年期間,如此誇張的剪紙,是窗花的變異,我更是沒見過。

  小時候,我看鄰家的小姐姐或阿姨剪窗花,順便要幾朵,拿回家貼在窗上。我有了兒子之後,孩子小時候磨我教他剪窗花,我不會,便把他推給我母親,告訴他:奶奶會,你找奶奶去!其實,奶奶只剪過鞋樣子,哪裡會剪窗花?但被孩子磨得沒法子了,只好從針線笸籮里拿出剪子,把大紅紙一折好幾疊,便開始隨便亂剪一通。誰想到,兒子把紅紙抖摟開一看,儘管不知道剪的是什麼圖案,但那樣像抽象派的圖案,還挺新鮮,挺好看呢!這樣剪窗花,一點兒都不難嘛,兒子抄起剪刀,也開始學奶奶的樣子,剪出一床窗花來。我家那年春節的窗戶上,貼的全是奶奶和她的小孫子剪的窗花。

  流年似水,一晃又到春節。兒子的兩個孩子,一個八歲,一個十歲了。他們跟爸爸新學會了剪紙,年前剪了一堆的窗花,比他們的爸爸當年剪得有章法多了。雖然人在國外,但兩人準備春節前送給每個同學一個窗花,讓他們那些外國同學也知道中國人過年貼的窗花是什麼樣子。視頻通話的時候,我讓他們兩人先別忙着把窗花送同學,一人選出自己最得意的一個窗花,先送給我。今年貼在我家的窗上,他們和他們的窗花,陪我們老兩口一起過年。

本站聲明:網站內容來http://www.societynews.cn/html/wh/fq/,如有侵權,請聯繫我們,我們將及時處理

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

七個生產案例告訴你BATJ為何選擇ElasticSearch!應用場景和優勢!_貨運

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

本文來源於公眾號【胖滾豬學編程】,轉載請註明出處。

從今天開始,想和你一起死磕ElasticSearch,學習分佈式搜索引擎,跟着胖滾豬就對了!

既然是ES的第一課,那麼最重要的是讓你愛上它!不想說那些單純的優勢、概念了,直接上大廠的生產案例,才是最能吸引你的!跟着大廠走,沒問題的!

為啥選擇ES?

一個技術服務組件,首先需要了解全面它的使用場景,才能更針對性的去研究及推廣。因此第一要務是搞懂為什麼要學習ElasticSearch,開頭po先一張排行圖,大哥的地位可不是瞎搞來的,沒點實力能上位?憑這排名就是你要學習它的理由!

憑啥排這麼前呢?不就是個搜索引擎嗎。額,也許提到Elasticseach,你第一反應就是”搜索引擎”。類似百度搜索、淘寶搜索那種。而我寫這篇文章就是為了糾正你這個”錯誤”的觀點。

Elasticseach 確實是做搜索引擎出家的,但是到現在已經進化成了一個全能型的數據產品。因此你的思維決不能限制在搜索引擎上。

本文通過一線大廠的八個案例,全方位讓你了解ElasticSearch的應用場景和優勢,包括:

  • 日誌實時分析
  • 搜索服務
  • 數據分析
  • 數據監控
  • 查詢服務
  • 後端存儲

ElasticSearch在騰訊的應用

ElasticSearch在騰訊的應用非常廣泛,主要有三:日誌實時分析場景、搜索服務、時序數據分析。

  • 搜索服務: 例如像騰訊文檔基於 ES 做全文檢索,電商客戶拼多多、蘑菇街等大量的商品搜索都是基於 ES。
  • 日誌分析: 這個是 ES 應用最廣泛的領域,支持全棧的日誌分析,包括各種應用日誌、數據庫日誌、用戶行為日誌、網絡數據、安全數據等等。ES 擁有一套完整的日誌解決方案,可以秒級實現從採集到展示。
  • 時序分析: 典型的場景是監控數據分析,比如雲監控,整個騰訊雲的監控都是基於 ES 的。此外還包括物聯網場景,也有大量的時序數據。時序數據的特點是寫入吞吐量特別高,ES 支持的同時也提供了豐富的多維統計分析算子。

日誌實時分析

典型日誌如下:

  • 運營日誌,比如慢日誌、異常日誌,用來定位業務問題;
  • 業務日誌,比如用戶的點擊、訪問日誌,可以用來分析用戶行為;
  • 審計日誌,可以用於安全分析。ES 很完美的解決了日誌實時分析的需求,它具有如下特點:

Elastic 生態提供了完整的日誌解決方案,任何一個開發、運維同學使用成熟組件,通過簡單部署,即可搭建起一個完整的日誌實時分析服務。

  • 在 Elastic 生態中,日誌從產生到可訪問一般在 10s 級。相比於傳統大數據解決方案的幾十分鐘、小時級,時效性非常高。ES 擁有一套完整的日誌解決方案(ELK),可以秒級實現從採集到展示。

  • 由於支持倒排索引、列存儲等數據結構,ES 提供非常靈活的搜索分析能力。

  • 支持交互式分析,即使在萬億級日誌的情況下,ES 搜索響應時間也是秒級。

日誌是互聯網行業最基礎、最廣泛的數據形式,ES 非常完美的解決了日誌實時分析場景,這也是近幾年 ES 快速發展的一個重要原因

搜索服務

搜索服務,典型場景包含:商品搜索,類似京東、淘寶、拼多多中的商品搜索;APP 搜索,支持應用商店裡的應用搜索;站內搜索,支持論壇、在線文檔等搜索功能。我們支持了大量搜索服務,它們主要有以下特點:

  • 高性能:單個服務最大達到 10w+ QPS,平響 20ms~,P95 延時小於 100ms。
  • 強相關:搜索體驗主要取決於搜索結果是否高度匹配用戶意圖,需要通過正確率、召回率等指標進行評估。
  • 高可用:搜索場景通常要求高可用性,支持單機房故障容災。任何一個電商服務,如淘寶、京東、拼多多,只要故障一個小時就可以上頭條。

時序數據分析

時序數據分析,典型的時序數據包含:Metrics,即傳統的服務器監控;整個騰訊雲的監控都是基於 ES 的。APM,應用性能監控;物聯網數據,智能硬件、工業物聯網等產生的傳感器數據。時序數據的特點是寫入吞吐量特別高,ES 支持的同時也提供了豐富的多維統計分析算子。這類場景具有以下特點:

  • 高併發寫入:線上單集群最大規模達到 600+節點、1000w/s 的寫入吞吐。

  • 高查詢性能:要求單條曲線 或者單個時間線的查詢延時在 10ms~。

  • 多維分析:要求靈活、多維度的統計分析能力,比如我們在查看監控的時候,可以按照地域、業務模塊等靈活的進行統計分析。

上面通過騰訊的案例我們了解了三大應用場景,

  • 日誌實時分析場景

  • 搜索服務

  • 時序數據分析

另外從這三大應用場景我們也可以歸納出ES的幾大優勢:

1、具有高可用性、高擴展性;

2、查詢速度快,性能佳;

3、搜索功能強大,高度匹配用戶意圖。

因此,可以看出,ES在日誌實時分析和搜索方面的應用優勢簡直是無敵的!起碼目前,在這兩方面,還沒有強勁的對手!

ElasticSearch在京東的應用

通過京東的案例,聊一聊ES在查詢、檢索、數據分析方面的應用場景

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

由於較高的性能和較低的使用門檻,京東內部有很多的場景都在使用 Elasticsearch。覆蓋了京東多條業務線,同時也覆蓋了很多應用場景:

補充關係型數據庫的結構化數據查詢

主要應用的業務是商品、促銷、優惠券、訂單、收銀台、物流、對賬、評論等大數據量查詢。此場景的核心訴求是高性能、穩定性和高可用性,部分場景會有檢索要求,通常用於加速關係型數據庫,業務系統通過 binlog 同步或業務雙寫完成數據同步。

全文檢索功能

主要的應用場景是應用、安全、風控、交易等操作日誌,以及京東部分品類商品搜索。此類日誌化場景對寫要求很高,查詢性能及高可用等要求相對較低,大的業務寫會達到數千萬 / 秒,存儲以 PB 為單位來計算。
這些場景對磁盤、內存有比較高的要求,因此,京東也做了相應優化,用於減少內存消耗,提升磁盤整體使用率,使用更廉價的磁盤來降低成本等等。

實時數據分析引擎,形成統計報表

主要應用的業務是物流單的各種分析、訂單數據分析、用戶畫像等。因為業務數據分析緯度較多,flink、storm 等流式分析對於某些報表場景不太適用,批處理實時性又成為問題,所以近實時分析的 Elasticsearch 就成為了這些業務的選擇。

從京東的案例中,我們似乎看到了,可以利用ES在某些場景下代替關係型數據庫哦!不僅如此,ES在實時數據分析領域,居然也有一席之地!

ElasticSearch在去哪兒的應用

通過去哪兒的案例,聊一聊ES在查詢方面的應用場景,可以簡單的理解為”代替”mysql。注意代替加了引號,閉着眼睛想都不可能完全代替。比如事務性。

15年去哪兒網酒店日均訂單量達到30w+,隨着多平台訂單的聚合日均訂單能達到100w左右。

原來採用的熱表分庫方式,即將最近6個月的訂單的放置在一張表中,將歷史訂單放在在history表中。history表存儲全量的數據,當用戶查詢的下單時間跨度超過6個月即查詢歷史訂單表,此分表方式熱表的數據量為4000w左右,當時能解決的問題。但是顯然不能滿足攜程藝龍訂單接入的需求。

如果繼續按照熱表方式,數據量將超過1億條。全量數據表保存2年的可能就超過4億的數據量。所以尋找有效途徑解決此問題迫在眉睫。由於對這預計4億的數據量還需按照預定日期、入住日期、離店日期、訂單號、聯繫人姓名、電話、酒店名稱、訂單狀態……等多個條件查詢。所以簡單按照某一個維度進行分表操作沒有意義。

顯然只通過DB來支撐大量的查詢是不可取的,同時對於一些複雜的查詢,Mysql支持得不夠友好,所以Elasticsearch分佈式搜索儲存集群的引入,就是為了解決訂單數據的存儲與搜索的問題。

對訂單模型進行抽象和分類,將常用搜索字段和基礎屬性字段剝離。DB做分庫分表,存儲訂單詳情;Elasticsearch存儲搜素字段。

訂單複雜查詢直接走Elasticsearch,基於OrderNo的簡單查詢走DB,如下圖所示。

從去哪兒的案例中,我們似乎看到了,關係型數據庫撐不起的複雜查詢,ES可以勝任

總結

什麼時候應該用ElasticSearch?

1、典型搜索場景:閉着眼用它!

2、典型日誌分析場景:閉着眼用它!

3、關係型數據庫查詢有瓶頸:考慮下用它!為啥是考慮?ES的優點在於查詢,然而實踐證明,在被作為數據庫來使用,即寫完馬上查詢會有延遲。

4、數據分析場景:考慮下用它!為啥是考慮?簡單通用的場景需求可以大規模使用,但在特定業務場景領域,還是要選擇更加專業的數據產品,如複雜聚合,ClickHouse相比 Elasticserach 做億級別數據深度聚合需求會更加合適。

ElasticSearch有什麼優勢呢?

1、很簡便的橫向擴容,分佈式的架構,可以輕鬆地對資源進行橫向縱向擴縮容,可以滿足不同數據量級及查詢場景對硬件資源的需求。能由數百台到萬台機器搭建滿足PB級的快速搜索,也能搭建單機版服務小公司。

2、查詢速度快:ES底層採用Lucene作為搜索引擎,並在此之上做了多重優化,保證了用戶對數據查詢數據的需求。可”代替”傳統關係型數據庫,也可用於複雜數據分析,海量數據的近實時處理等。

3、相關性高:ES內部提供了完善的評分機制,會根據分詞出現的頻次等信息對文檔進行相關性排序,保證相關性越高的文檔排序越靠前。另外還提供了包括模糊查詢,前綴查詢,通配符查詢等在內的多種查詢手段,幫助用戶快速高效地進行檢索。

4、功能點多但使用比較簡便,開箱即用,性能優化比較簡單

5、生態圈豐富,社區活躍,適配多種工具。如下圖,處理日誌和輸出到Elasticsearch,您可以使用日誌記錄工具,如Logstash(www.elastic.co/products/logstash),搜索和可視化界面分析這些日誌,你可以使用Kibana(www.elastic.co/產品/ kibana),即傳說中的ELK技術棧。另外當前主流的大數據框架也幾乎都支持ES,比如Flink和ES就是個完美搭檔。

本文參考:

騰訊萬億級 Elasticsearch 技術解密

搜索引擎怎麼選?攜程酒店訂單Elasticsearch實戰

Elasticsearch在京東的使用場景

本文來源於公眾號:【胖滾豬學編程】。一枚集顏值與才華於一身,不算聰明卻足夠努力的女程序媛。用漫畫形式讓編程so easy and interesting!求關注!

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

CTR學習筆記&代碼實現6-深度ctr模型 後浪 xDeepFM/FiBiNET_網頁設計公司

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

xDeepFM用改良的DCN替代了DeepFM的FM部分來學習組合特徵信息,而FiBiNET則是應用SENET加入了特徵權重比NFM,AFM更進了一步。在看兩個model前建議對DeepFM, Deep&Cross, AFM,NFM都有簡單了解,不熟悉的可以看下文章最後其他model的博客鏈接。

以下代碼針對Dense輸入更容易理解模型結構,針對spare輸入的代碼和完整代碼
https://github.com/DSXiangLi/CTR

xDeepFM

模型結構

看xDeepFM的名字和DeepFM相似都擁有Deep和Linear的部分,只不過把DeepFM中用來學習二階特徵交互的FM部分替換成了CIN(Compressed Interactino Network)。而CIN是在Deep&Cross的DCN上進一步改良的得到。整體模型結構如下

我們重點看下CIN的部分,和paper的notation保持一致,有m個特徵,每個特徵Embedding是D維,第K層的CIN有\(H_k\)個unit。CIN第K層的計算分為3個部分分別對應圖a-c:

  1. 向量兩兩做element-wise product, 時間複雜度\(O(m*H_{k-1}*D)\)
    對輸入層和第K-1層輸出,做element-wise乘積進行兩兩特徵交互,得到\(m*H_{k-1}\)個D維向量矩陣,如果CIN只有一層,則和FM, NFM,AFM的第一步相同。FM 直接聚合成scaler,NFM沿D進行sum_pooling,而AFM加入Attention沿D進行weighted_pooling。忽略batch的矩陣dimension變化如下

\[z^k = x^0 \odot x^{k-1} = (D * m* 1) \odot (D * 1* H_{k-1}) = D * m*H_{k-1} \]

  1. Feature Map,空間複雜度\(O(H_k *H_{k-1} *m)\),時間複雜度\(O(H_k *H_{k-1} *m*D)\)
    \(W_k \in R^{H_{k-1}*m *H_k}\) 是第K層的權重向量,可以理解為沿Embedding做CNN。每個Filter對所有兩兩乘積的向量進行加權求和得到 \(1*D\)的向量 一共有\(H_k\)個channel,輸出\(H_k * D\)的矩陣向量。

\[w^k \bullet z^k = (H_k *H_{k-1} *m)* (m*H_{k-1}*D) = H_k *D \]

  1. Sum Pooling
    CIN對每層的輸出沿Dimension進行sum pooling,得到\(H_k*1\)的輸出,然後把每層輸出concat以後作為CIN部分的輸出。

CIN每一層的計算如上,T層CIN每一層都是上一次層的輸出和第一層的輸入進行交互得到更高一階的交互信息。假設每層維度一樣\(H_k=H\), CIN 部分整體時間複雜度是\(O(TDmH^2)\),空間複雜度來自每層的Filter權重\(O(TmH^2)\)

CIN保留DCN的任意高階和參數共享,兩個主要差別是

  • DCN是bit-wise,CIN是vector-wise。DCN在做向量乘積時不區分Field,直接對所有Field拼接成的輸入(m*D)進行外積。而CIN考慮Field,兩兩vector進行乘積
  • DCN使用了ResNet因為多項式的核心只用輸出最後一層,而CIN則是每層都進行pooling后輸出

CIN的設計還是很巧妙滴,不過。。。吐槽小分隊上線: CIN不論是時間複雜度還是空間複雜度都比DCN要高,感覺更容易過擬合。至於說vector-wise的向量乘積要比bit-wise的向量乘積要好,這。。。至少bit-wise可以不限制embedding維度一致, 但vector-wise嘛我實在有些理解無能,明白的童鞋可以comment一下

代碼實現

def cross_op(xk, x0, layer_size_prev, layer_size_curr, layer, emb_size, field_size):
    # Hamard product: ( batch * D * HK-1 * 1) * (batch * D * 1* H0) -> batch * D * HK-1 * H0
    zk = tf.matmul( tf.expand_dims(tf.transpose(xk, perm = (0, 2, 1)), 3),
                    tf.expand_dims(tf.transpose(x0, perm = (0, 2, 1)), 2))

    zk = tf.reshape(zk, [-1, emb_size, field_size * layer_size_prev]) # batch * D * HK-1 * H0 -> batch * D * (HK-1 * H0)
    add_layer_summary('zk_{}'.format(layer), zk)

    # Convolution with channel = HK: (batch * D * (HK-1*H0)) * ((HK-1*H0) * HK)-> batch * D * HK
    kernel = tf.get_variable(name = 'kernel{}'.format(layer),
                             shape = (field_size * layer_size_prev, layer_size_curr))
    xkk = tf.matmul(zk, kernel)
    xkk = tf.transpose(xkk, perm = [0,2,1]) # batch * HK * D
    add_layer_summary( 'Xk_{}'.format(layer), xkk )
    return xkk


def cin_layer(x0, cin_layer_size, emb_size, field_size):
    cin_output_list = []

    cin_layer_size.insert(0, field_size) # insert field dimension for input
    with tf.variable_scope('Cin_component'):
        xk = x0
        for layer in range(1, len(cin_layer_size)):
            with tf.variable_scope('Cin_layer{}'.format(layer)):
                # Do cross
                xk = cross_op(xk, x0, cin_layer_size[layer-1], cin_layer_size[layer],
                              layer, emb_size, field_size ) # batch * HK * D
                # sum pooling on dimension axis
                cin_output_list.append(tf.reduce_sum(xk, 2)) # batch * HK

    return tf.concat(cin_output_list, axis=1)

@tf_estimator_model
def model_fn_dense(features, labels, mode, params):
    dense_feature, sparse_feature = build_features()
    dense_input = tf.feature_column.input_layer(features, dense_feature)
    sparse_input = tf.feature_column.input_layer(features, sparse_feature)

    # Linear part
    with tf.variable_scope('Linear_component'):
        linear_output = tf.layers.dense( sparse_input, units=1 )
        add_layer_summary( 'linear_output', linear_output )

    # Deep part
    dense_output = stack_dense_layer( dense_input, params['hidden_units'],
                               params['dropout_rate'], params['batch_norm'],
                               mode, add_summary=True )
    # CIN part
    emb_size = dense_feature[0].variable_shape.as_list()[-1]
    field_size = len(dense_feature)
    embedding_matrix = tf.reshape(dense_input, [-1, field_size, emb_size]) # batch * field_size * emb_size
    add_layer_summary('embedding_matrix', embedding_matrix)

    cin_output = cin_layer(embedding_matrix, params['cin_layer_size'], emb_size, field_size)

    with tf.variable_scope('output'):
        y = tf.concat([dense_output, cin_output,linear_output], axis=1)
        y = tf.layers.dense(y, units= 1)
        add_layer_summary( 'output', y )

    return y

FiBiNET

模型結構

看FiBiNET前可以先了解下Squeeze-and-Excitation Network,感興趣可以看下這篇博客Squeeze-and-Excitation Networks。

FiBiNET的主要創新是應用SENET學習每個特徵的重要性,加權得到新的Embedding矩陣。在FiBiNET之前,AFM,PNN,DCN和上面的xDeepFM都是在特徵交互之後才用attention, 加權等方式學習特徵交互的權重,而FiBiNET在保留這部分的同時,在Embedding部分就考慮特徵自身的權重。模型結構如下

原始Embedding,和經過SENET調整過權重的新Embedding,在Bilinear-interaction層學習二階交互特徵,拼接后,再經過MLP進一步學習高階特徵。和paper notation保持一致(啊啊啊大家能不能統一下notation搞的我自己看自己的註釋都蒙圈),f個特徵,k維embedding

SENET層

SENET層學習每個特徵的權重對Embedding進行加權,分為以下3步

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

  1. Squeeze
    \(f*k\)的Embedding矩陣壓縮成\(f*1\), 壓縮方式不固定,SENET原paper用的max_pooling,作者用的sum_pooling,感覺這裏壓縮方式應該取決於Embedding的信息表達

\[\begin{align} E &= [e_1,…,e_f] \\ Z &= [z_1,…,z_f] \\ z_i &= F_{squeeze}(e_i) = \frac{1}{k}\sum_{i=1}^K e_i \\ \end{align} \]

  1. Excitation
    Excitation是一個兩層的全連接層,通過先降維再升維的方式過濾一些無用特徵,降維的幅度通過額外變量\(r\)來控制,第一層權重\(W_1 \in R^{f*f/r}\),第二層權重\(W_2 \in R^{f/r*f}\)。這裏r越高,壓縮的幅度越高,最終的權重會更集中,反之會更分散。

\[A = \sigma_2(W_2·\sigma_1(W_1·Z)) \]

  1. Re-weight
    最後一步就是用Excitation得到的每個特徵的權重對Embedding進行加權得到新Embedding

\[E_{new} = F_{Reweight}(A,E) = [a_1·e_1, …,a_f·e_f ] \]

在收入數據集上進行嘗試,r=2時會有46%的embedding特徵權重為0,所以SENET會在特徵交互前先過濾部分對target無用的特徵來增加有效特徵的權重

Bilinear-Interaction層

作者提出內積和element-wise乘積都不足以捕捉特徵交互信息,因此進一步引入權重W,以下面的方式進行特徵交互

\[v_i · W \odot v_j \]

其中W有三種選擇,可以所有特徵交互共享一個權重矩陣(Field-All),或者每個特徵和其他特徵的交互共享權重(Field-Each), 再或者每個特徵交互一個權重(Field-Interaction) 具體的優劣感覺需要casebycase來試,不過一般還是照着數據越少參數越少的邏輯來整。

原始Embedding和調整權重后的Embedding在Bilinear-Interaction學習交互特徵后,拼接成shallow 層,再經過全連接層來學習更高階的特徵交互。後面的屬於常規操作這裏就不再細說。

我們不去吐槽FiBiNET可以加入wide&deep框架來捕捉低階特徵信息和任意高階信息,更多把FiBiNET提供的SENET特徵權重的思路放到自己的工具箱中就好。

代碼實現

def Bilinear_layer(embedding_matrix, field_size, emb_size, type, name):
    # Bilinear_layer: combine inner and element-wise product
    interaction_list = []
    with tf.variable_scope('BI_interaction_{}'.format(name)):
        if type == 'field_all':
            weight = tf.get_variable( shape=(emb_size, emb_size), initializer=tf.truncated_normal_initializer(),
                                      name='Bilinear_weight_{}'.format(name) )
        for i in range(field_size):
            if type == 'field_each':
                weight = tf.get_variable( shape=(emb_size, emb_size), initializer=tf.truncated_normal_initializer(),
                                          name='Bilinear_weight_{}_{}'.format(i, name) )
            for j in range(i+1, field_size):
                if type == 'field_interaction':
                    weight = tf.get_variable( shape=(emb_size, emb_size), initializer=tf.truncated_normal_initializer(),
                                          name='Bilinear_weight_{}_{}_{}'.format(i,j, name) )
                vi = tf.gather(embedding_matrix, indices = i, axis =1, batch_dims =0, name ='v{}'.format(i)) # batch * emb_size
                vj = tf.gather(embedding_matrix, indices = j, axis =1, batch_dims =0, name ='v{}'.format(j)) # batch * emb_size
                pij = tf.matmul(tf.multiply(vi,vj), weight) # bilinear : vi * wij \odot vj
                interaction_list.append(pij)

        combination = tf.stack(interaction_list, axis =1 ) # batch * emb_size * (Field_size * (Field_size-1)/2)
        combination = tf.reshape(combination, shape = [-1, int(emb_size * (field_size * (field_size-1) /2)) ]) # batch * ~
        add_layer_summary( 'bilinear_output', combination )

    return combination


def SENET_layer(embedding_matrix, field_size, emb_size, pool_op, ratio):
    with tf.variable_scope('SENET_layer'):
        # squeeze embedding to scaler for each field
        with tf.variable_scope('pooling'):
            if pool_op == 'max':
                z = tf.reduce_max(embedding_matrix, axis=2) # batch * field_size * emb_size -> batch * field_size
            else:
                z = tf.reduce_mean(embedding_matrix, axis=2)
            add_layer_summary('pooling scaler', z)

        # excitation learn the weight of each field from above scaler
        with tf.variable_scope('excitation'):
            z1 = tf.layers.dense(z, units = field_size//ratio, activation = 'relu')
            a = tf.layers.dense(z1, units= field_size, activation = 'relu') # batch * field_size
            add_layer_summary('exciitation weight', a )

        # re-weight embedding with weight
        with tf.variable_scope('reweight'):
            senet_embedding = tf.multiply(embedding_matrix, tf.expand_dims(a, axis = -1)) # (batch * field * emb) * ( batch * field * 1)
            add_layer_summary('senet_embedding', senet_embedding) # batch * field_size * emb_size

        return senet_embedding

@tf_estimator_model
def model_fn_dense(features, labels, mode, params):
    dense_feature, sparse_feature = build_features()
    dense_input = tf.feature_column.input_layer(features, dense_feature)
    sparse_input = tf.feature_column.input_layer(features, sparse_feature)

    # Linear part
    with tf.variable_scope('Linear_component'):
        linear_output = tf.layers.dense( sparse_input, units=1 )
        add_layer_summary( 'linear_output', linear_output )

    field_size = len(dense_feature)
    emb_size = dense_feature[0].variable_shape.as_list()[-1]
    embedding_matrix = tf.reshape(dense_input, [-1, field_size, emb_size])

    # SENET_layer to get new embedding matrix
    senet_embedding_matrix = SENET_layer(embedding_matrix, field_size, emb_size,
                                         pool_op = params['pool_op'], ratio= params['senet_ratio'])

    # combination layer & BI_interaction
    BI_org = Bilinear_layer(embedding_matrix, field_size, emb_size, type = params['bilinear_type'], name = 'org')
    BI_senet = Bilinear_layer(senet_embedding_matrix, field_size, emb_size, type = params['bilinear_type'], name = 'senet')

    combination_layer = tf.concat([BI_org, BI_senet] , axis =1)

    # Deep part
    dense_output = stack_dense_layer(combination_layer, params['hidden_units'],
                               params['dropout_rate'], params['batch_norm'],
                               mode, add_summary=True )

    with tf.variable_scope('output'):
        y = dense_output + linear_output
        add_layer_summary( 'output', y )

    return y

CTR學習筆記&代碼實現系列

https://github.com/DSXiangLi/CTR
CTR學習筆記&代碼實現1-深度學習的前奏 LR->FFM
CTR學習筆記&代碼實現2-深度ctr模型 MLP->Wide&Deep
CTR學習筆記&代碼實現3-深度ctr模型 FNN->PNN->DeepFM
CTR學習筆記&代碼實現4-深度ctr模型 NFM/AFM
CTR學習筆記&代碼實現5-深度ctr模型 DeepCrossing -> Deep&Cross

Ref

  1. Jianxun Lian, 2018, xDeepFM: Combining Explicit and Implicit Feature Interactions for Recommender Systems
  2. Tongwen Huang, 2019, FiBiNET: Combining Feature Importance and Bilinear feature Interaction for Click-Through Rate Prediction
  3. Jie Hu, 2017, Squeeze-and-Excitation Networks
  4. https://zhuanlan.zhihu.com/p/72931811
  5. https://zhuanlan.zhihu.com/p/79659557
  6. https://zhuanlan.zhihu.com/p/57162373
  7. https://github.com/qiaoguan/deep-ctr-prediction

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

春節假期第四天全國主要道路交通安全順暢_包裝設計

※產品缺大量曝光嗎?你需要的是一流包裝設計!

窩窩觸角包含自媒體、自有平台及其他國家營銷業務等,多角化經營並具有國際觀的永續理念。

新華社北京1月27日電 公安部交管局27日發布信息,春節假期第四天,各主要高速公路、國省道幹線公路交通安全順暢,根據全國35條高速公路200個重要通道監測節點流量監測情況,交通總流量與去年同期相比下降39.9%。截至17時,未發生長時間長距離交通擁堵,未接報一次死亡5人以上較大交通事故。

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

上新台中搬家公司提供您一套專業有效率且人性化的辦公室搬遷、公司行號搬家及工廠遷廠的搬家服務

全國公安交管部門根據公安部統一部署,在當地黨委政府和公安機關的統一指揮下,主動擔當、积極作為,統籌春節假日交通安保和交通應急管理,會同和配合有關部門嚴密重點路段管控、嚴密重點部位防護、嚴密重點車輛查控,全力投入疫情防控工作,全力保障道路交通安全暢通。據統計,各地公安交管部門共出動警力18萬餘人次,出動警車7萬餘輛次,啟動交警執法站4100餘個,設立臨時執勤點1.2萬餘個。

根據中央氣象台預報,27日至28日,西南部局地有大雪或暴雪。27日夜間至28日早晨,湖北東部、湖南北部、江西東北部、山東中部、江蘇北部等地部分地區將有大霧天氣,局部有濃霧或強濃霧。公安部交管局提示廣大駕駛人朋友:霧天行車要打開霧燈,控制車速、保持安全車距;在冰雪路面行車時,要做到“緩加油、輕減速、慢轉彎”;請牢記“安全帶——生命帶”,駕車一定系好安全帶,莫忘為兒童選用適合其年齡、體重的兒童安全座椅。特別是請按照各地疫情防控工作的要求,盡量減少交通出行。

本站聲明:網站內容來http://www.societynews.cn/html/wh/fq/,如有侵權,請聯繫我們,我們將及時處理

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網動廣告出品的網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上她。

小米 POCO 官方 Facebook 粉專成立、官網上線,即將以 POCO 品牌「重返」台灣市場_貨運

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

 之所以說 POCO 即將「重返」台灣市場,也是因為這已經不是 POCO 第一次有產品在台灣推出。回顧 2018 年,當時還是小米旗下品牌的 POCOPHONE(POCO)在台灣推出萬元價位的旗艦手機 POCOPHONE F1 ,不僅當年成為許多追求性價比旗艦手機的消費者的首選之一,該款手機也獲得 MKBHD 評選為 2018 年最佳平價手機。然而,即便在那之後 POCO 仍有在印度推出新機,不過在台灣就沒有再推出新產品。

▲圖片來源:POCO Taiwan(Facebook)

小米 POCO 官方 Facebook 粉專成立、官網上線,即將以 POCO 品牌「重返」台灣市場

2020 年初, POCO 在印度與小米拆分、成為獨立的品牌後,在去年 11 月底也宣布 POCO 全球成為獨立品牌並成為 POCO Global 。稍早小米台灣 Xiaomi Taiwan 粉絲專頁分享了 POCO Taiwan 的粉絲專頁開張,暗示著 POCO 即將「重返」台灣市場。

POCO Taiwan 粉絲專頁在近期才剛成立:

▲圖片來源:POCO Taiwan(Facebook)

今(4)日稍早, POCO Taiwan 也張貼第一則貼文:

▲圖片來源:POCO Taiwan(Facebook)

檢視 POCO Taiwan 粉絲專頁是在 2020 年 12 月 24 日成立,並於 12 月 30 日與全球 POCO 全球的粉絲專頁進行合併:

▲圖片來源:POCO Taiwan(Facebook)

除了 Facebook 粉絲專頁,筆者稍早也查到了 POCO Taiwan 獨立的官方網站也已經悄悄上線,不再像當年 POCOPHONE F1 是小米台灣官網內的一款機型。
雖然,目前尚未公開任何關於 POCO 的消息、銷售的產品、會員制度也尚未開放註冊,不過種種跡象也很明顯代表接下來 POCO 將會以獨立品牌的方式回歸台灣市場。

▲圖片來源:POCO Taiwan (官網)

在購買管道部分,從 POCO Taiwan 官網可以看到線上官方線上合作通路有小米台灣,而其他通路則有小米之家、小米專賣店、PChome24h 購物以及聯強國際。

▲圖片來源:POCO Taiwan (官網)

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

自從 POCO 成為獨立品牌至今陸續推出包括 POCO F2 Pro、 POCO X2、POCO X3 NFC 、 POCO M2 Pro 以及 POCO M3 等多款手機。
想必大家最關心的還是回歸台灣市場的 POCO 手機會是哪一款?日前有消息指出 POCO M3 可能會最快在台灣上市,這款擁有 6000mAh 大電量中階手機搭載高通 Snapdragon 662 處理器、配備 6.53 吋 FHD+ 水滴全螢幕、 4800 萬像素三鏡頭主相機,傳聞預計將引進 4GB+64GB 與 4GB+128GB 兩個版本,至於確切的消息還是得靜候台灣官方公佈為準。

▲圖片來源:POCO Global (官網)

去年 POCO 推出搭載高通 Snapdragon 865 處理器的 F2 Pro 旗艦手機,其實就是 Redmi K30 Pro 針對國際市場的更名版本機型。日前,我們也曾報導過 POCO 印度預告將在近期推出更平價的 POCO F2 ,從目前洩漏的消息傳聞 POCO F2 搭載和 POCO X3 NFC 相同的高通 S732G 處理器、120Hz 更新率 AMOLED 顯示螢幕、四鏡頭主相機,不過電池容量較小僅有 4250mAh 電池容量,確切規格仍得等待 POCO 官方正式發佈為準。

POCO Taiwan:
Facebook 粉絲專頁(點我前往)|官方網站(點我前往)

延伸閱讀:
realme V15 真機曝光:6400 萬像素三鏡頭主相機長續航中階新機,將於 1 月 7 日發表

小米有品推出 Lydsto 手持吸塵打氣機,眾籌價約 860 元

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。