我拋一個公司最近的技術難點,各位幫忙想想。 兩個隊列,一個隊列100萬數據左右,一個隊列10萬數據左右,這兩個隊列都在動態補充和消耗。 第一個隊列需要多維排序,取出最優的與第二個隊列的數據一起處理, 處理完成后如果沒有用光,還會回到第一個隊列。 希望能夠盡可能取出更優的和速度較快。[北京-陰空]
北京-陰空(-) 15:51:14
這是個投標的場景。 如果標的資產是1萬,但是第一個隊列里有100萬,就會用1萬,還生99萬繼續回到隊列。
深圳-平凡(-) 15:51:42
你們是做優先匹配嗎?
北京-陰空(-) 15:51:49
我本來想到用多維樹來解決,但是,因為隊列一直變化, 用樹就不合適了。我們根據這個隊列去向存管銀行發請求。
北京-哇咔咔(-) 15:53:52
似乎 應該從隊列2拿出數據,從隊列1取頭數據,算完了,再把隊列1的數據放回去;重復這個過程
深圳-平凡(-) 15:54:43
問題就在第一個隊列的動態多維排序里
北京-哇咔咔(-) 15:54:55
從隊列1拿出數據,再從隊列2遍歷數據并計算,就不對了。因為計算完一條隊列2的數據以后,這時候從隊列1拿到的數據可能就不是最優值了
北京-哇咔咔(-) 15:55:24
不過為什么要有隊列2
北京-陰空(-) 15:55:27
會導致匹配速度過慢吧。 每次都要等處理完了重新排序是吧。
北京-陰空(-) 15:55:43
相當于隊列一是錢,二是資產。
成都-梅小西(-) 15:56:16
隊列1是資金,隊列2是標,對不對
深圳-平凡(-) 15:56:20
第一個隊列是用戶買你們的產品,第二個隊列是產品資金對接到真實債權?
北京-陰空(-) 15:56:20
對的
成都-梅小西(-) 15:56:28
就是隊列1的資金去投隊列2
成都-梅小西(-) 15:56:36
還要最優組合
成都-梅小西(-) 15:56:47
這個東西涉及并發啊,要注意安全, 錢要是出問題了就麻煩
北京-陰空(-) 15:56:47
恩,多維排序。現在的解決方案是。 都放到數據庫里。。。order by多個字段。。
深圳-平凡(-) 15:57:54
多維排序是P2P的匹配規則,比如監管要求的不能期限錯配,公司的利率差最優值這些
北京-陰空(-) 15:58:30
比如,a.b 兩個用戶來公司投資。 這兩個人投資的產品分別是預期8,9的利率,(第一個維度),然后每個人投資的錢只有一部分投到了標的上(第二個維度),每個人的錢到期的時間不同(第三個維度),現在希望根據上面幾個維度,把這些錢投到,資產端過來的標的上。就是兩個隊列出來的數據match下。 然后做出來。 第一個隊列的數據,如果還有錢剩下來還要回去。
北京-Easy哥(-) 15:59:53
a b就是那2個隊列? 一個是決策 一個資產轉移
北京-陰空(-) 16:00:01
我想到用多維樹做。 但是每次回來修改都需要鎖住樹。。。還是 隊列是 <源 利率 投的錢 到期時間> 另一個隊列是 <標>, 決策 的部分你加個時窗就好了,不要是實時的, 這個意思? 比如每5s排一次序,排完之后,轉移一次資產, 然后 產出 2個的結合?
北京-哇咔咔(-) 16:00:18
ignite、disruptor、hazelcast可以研究一下
北京-陰空(-) 16:01:04
基本喜神的意思吧, 對的
北京-Easy哥(-) 16:01:57
標有自己的屬性么?比如 錢 到期時間 利率?
北京-陰空(-) 16:02:20
標的問題不用考慮。
北京-陰空(-) 16:02:46
恩,easy個說的大概就是那樣。 就是這個隊列里都是對象,排序根據這個對象的多個屬性。
成都-梅小西(-) 16:02:53
他的意思是,按照各種維度排序后去投標。比如按照錢多錢少排序,然后投標,還有剩下的,就按到期時間排序,再去投標
北京-Easy哥(-) 16:03:01
感覺 根據這個幾個緯度做倒排索引 然后 做個交集就出來了
北京-陰空(-) 16:03:19
@成都-梅小西
是根據多個維度排好序了。。投標。
北京-Easy哥(-) 16:03:33
反過來做就好做很多
成都-梅小西(-) 16:03:53
哦,你是說排序都搞好了?
成都-梅小西(-) 16:04:04
每個維度排序都搞好了?
北京-陰空(-) 16:04:08
沒有。。排序是個麻煩的地方。主要是不能等太久
北京-陰空(-) 16:05:01
因為這個排序涉及到了用戶的投資是否能夠接近預期年利率。
北京-Easy哥(-) 16:05:02
用標的特性去過濾投標的隊列
北京-陰空(-) 16:06:04
@深圳-平凡 現在這個內存的方案還沒有可以執行的。 因為用戶一直在投資。 匹配玩后的資產還可能回來。鎖的話頻率太高了
北京-喜(-) 16:06:06
鎖的這個事情,改成定期排期吧,不然你根本沒法處理,沒有快照現場,一直是動態的
北京-陰空(-) 16:06:40
定期排期,按照次優處理是吧, 定期排期是不是也得鎖一下。
成都-梅小西(-) 16:07:55
你打算作為job定期運行么?
北京-陰空(-) 16:07:56
@北京-Easy哥 我猜測是擔心如果這么做。 導致某些用戶的收益率夠了,有些用戶的不夠。
北京-喜(-) 16:08:20
還有個點是:你是想把錢都投出去,還是想把標的都賣出去( 不太懂業務,用詞不太準)
北京-陰空(-) 16:09:06
標的都賣出去,因為一般錢都比標的多。(目前來說)然后,還要讓用戶的預期收益率盡可能達標。
北京-喜(-) 16:09:06
改決策模型, 也就是說, 你的排序權重里,其實還有一列, 根據用戶的已投和回報率,來計算下一次該如何投的, 這一次給他比如2萬10%匯報的,用戶期望9%。下一次可能可以給他一個8.5%的, 歷史投的情況,也是決策因子
天津-coffee(-) 16:09:11
我們匹配就沒這么多維度
深圳-平凡(-) 16:09:15
完全實時是做不到的,受影響的數據時刻在變化。換成三個隊列可以嗎?
一個排序
一個排序后的數據
一個處理排序后的數據
北京-陰空(-) 16:10:50
這就是標的。
北京-喜(332069183) 16:10:53
當然, C端看到的和B端資產 不是一個維度的
北京-陰空(799036779) 16:11:19
這些里面對應的每個用戶的錢就是第一個隊列里的東西。
北京-陰空(-) 16:11:48
第一幅圖左側的利率是不一定的。 所有的標的都會優先給資產去匹配, 之后才考慮是否展示到前臺。
北京-喜(-) 16:11:51
用戶維度是按筆算的?每一筆里的歷史投遞情況,需要作為下一次的決策依據的。 你看下決策樹
北京-陰空(-) 16:12:14
一個產品一個用戶。 是一條數據
廣州-小護士<-> 16:12:56
沒懂業務背景, 主要是業務背景沒介紹清楚,突然來一段動態匹配問題,不好搞
北京-喜(-) 16:14:01
image.png
廣州-小護士<-> 16:14:21
感覺這個不是決策樹問題, 決策樹只是做用戶分群
北京-喜(-) 16:14:30
比如相親相了很多之后,后來決策可能變,比如去他媽的,長相不看了
北京-陰空(-) 16:14:59
@北京-喜 我也是你這個想法,打算把所有的數據壓倒這個樹里, 然后從中取數據去匹配。
北京-喜(-) 16:15:00
算法我是渣渣, 我只是告訴他 歷史因子是要加進來的
北京-陰空(-) 16:15:22
可是。 就是修改太頻繁。。每次修改涉及到了樹結構的變化。。
北京-喜(-) 16:15:34
改成定期的, 只要最后能達標即可, 實時是需要計算能力的
北京-陰空(-) 16:16:08
定期的也去給樹上鎖嗎
北京-喜(-) 16:16:29
需要優化你的投遞窗口, 排一次序,并行投。 投完之后,在排下一次,新排序,使用以前的投遞結果, 即便用戶不改,你的模型也是變化的
北京-陰空(-) 16:18:30
定期的時候是要上鎖是吧。 你說的優化投遞窗口有什么辦法嗎
北京-喜(-) 16:18:44
排和投 都需要改成并行的, 并行計算、逐級歸并, 提高效率 這不是鎖的問題
成都-梅小西(-) 16:20:04
讓你跑定期跑job,不需要鎖, 要實時的話,難度大
北京-喜(-) 16:21:22
排的時候不投,或者分批次投, 這個看你是并行之后,100W數據歸并完畢,再投. 還是說分段,比如分成128段并行排序,排到比如4段 就停止, 然后依次投, 第一段投完之后, 第1段如果有剩余,繼續排。 期間并行投第2端
北京-陰空(-) 16:22:44
一個隊列里是這個產品里用戶投資的錢。
匹配這個東西
廣州-小護士<-> 16:23:22
用戶投的錢,然后呢, 這個東西對應用戶每一筆錢還是多筆錢?
北京-陰空(-) 16:24:23
@北京-喜 這里沒懂,沒有排序的情況下就分成128段了嗎
北京-喜(-) 16:24:50
對
北京-陰空(-) 16:24:54
我們也是擔心并行的話算錯了。。
北京-喜(-) 16:25:07
你要看你的目標是什么
北京-陰空(-) 16:25:09
不是排好序了再分堆嗎。。
北京-喜(-) 16:25:16
這個目標是多次達成的 還是 單次達成的
北京-陰空(-) 16:25:23
多次
北京-喜(-) 16:25:34
那就是最終是對的就可以了
北京-陰空(-) 16:25:48
恩,最終盡可能優
北京-喜(-) 16:25:50
你可以加一個風險區間控制, 不斷優化這個流程
北京-陰空(-) 16:27:40
有個地方沒懂, 數據一開始分成128段。 那么都不能隨便從某一段取吧。都不知道哪段的是更優的。
北京-喜(-) 16:27:51
單次沒有最優解, 比如也可以按照排序 把錢分幾個檔,依據檔分標的, 我的意思是,比如有100W用戶, 50W一個批次投,50W一個批次投, 第一個50W整體 比如執行6個周期搞定, 這個你得提前排好序吧。第二個50W比如執行10個周期搞定
北京-陰空(-) 16:30:59
我懂了你的意思了。 在這五十萬內, 追求最優是吧。
北京-喜(-) 16:31:09
對的, 但是你要有風控
北京-陰空(-) 16:31:23
我靠。 牛逼啊
北京-喜(-) 16:31:30
就是標的端能不能滿足 用戶端的訴求
北京-陰空(-) 16:31:35
明白
北京-喜(-) 16:31:36
這個你們應該是有的吧 是題外的
北京-陰空(-) 16:31:49
別到最后。。就這五十萬的人投了最好的了。。相當于把原本資產端的排序擴展到了標的端
北京-喜(-) 16:32:16
如果你嫌排序慢, 可以并行排, 如果你嫌投遞慢 可以并行投, 單機搞不定,就分布式排,分布式投。 分布式排 就是大數據計算.
北京-陰空(-) 16:35:19
有兩個問題。 第一個是投完的數據,是不是直接放到最后的隊位,接著排就好。第二個問題是,這樣還需要定時嗎
北京-喜(-) 16:35:53
段位是你定的, 段不足的話,可以補位, 也可以不補, 比如新用戶的數據,補到第一個段, 假如段都滿了,可以加段, 第3個段產生了, 后面再優化,讓每個段內的數據分布,盡可能均勻, 比如你的排序,其實是計算 以及 權重累計的過程, 后續讓每個段內的權重分布趨勢 基本一致就可以了, 然后在把標的 也分成3段, 第一段錢,用第一段標的,或者標的的1/3. 你也可以把用戶的每筆投,切成幾段,比如用戶投的5W,8%回報:你切成1W6%,1W7%,1W8%,1W9%,1W10%
北京-陰空(-) 16:42:48
我感覺這個就太復雜了。 我們公司不一定能承受這個方法了
北京-喜(-) 16:43:30
這個是逐漸的,后面為了最求利潤,可能要切, 早期的話,是先滿足業務
北京-陰空(-) 16:43:54
假定已經按照預料的段位分好了。 用戶資產的隊列有10段。 第一段第一個去投,還有剩余這個時候要回到隊列。這個時候要重排序嗎
北京-喜(-) 16:44:40
要的
北京-陰空(-) 16:44:53
就是每一個重拍一次是吧。
北京-喜(-) 16:44:54
因為投遞結果,是下一次計算/排序的因子, 會影響對標的的選擇
北京-陰空(-) 16:45:53
image.png
北京-喜(-) 16:46:18
因為你把用戶的錢拆了嘛
北京-陰空(-) 16:46:20
我一開始的想法是這樣。 把隊列的數據壓倒這個樹里面。
北京-喜(-) 16:47:01
不用, 每個計算項, 你給個權重, 最后加權出來 整體按權重排即可
北京-陰空(-) 16:47:38
這個權重給不了好像
北京-喜(-) 16:47:49
權重值早期粗,后續不斷優化, 比如過期
北京-陰空(-) 16:48:10
這個好像公司給不出來這個東西,缺少對應的數據支持
北京-喜(-) 16:48:21
早期一刀切, 后期可能差幾天 都要算進去, 你的if else ,也是一刀切,也不是精細的。 本質上還不如權重
北京-陰空(-) 16:49:57
我記得之前我提過一個思路,就是算個分出來。 然后將多維度變成單維度排序。應該是類似你說的權重了
北京-喜(-) 16:50:49
對的, 你代碼寫出來的 和權重一樣的, 比如一個分支走if +1, 走else+0
北京-陰空(-) 16:51:20
對, 你模擬下你最簡單的場景, 就是這個. 但是在往后,權重能做的事情,可不是if else能搞定的
北京-陰空(-) 16:52:06
上次說分的情況。 沒有推動。。不知道是我人微言輕還是思路上不好。 我說下我理解的你的方法哈。兩邊隊列都分割成同樣的比例。 然后可以并行排序和并行投遞。 有新增的數據或者可以繼續使用的數據,先考慮回到原有的段,超額的話,新增段。不能新增吧。。新增的話兩邊不匹配了。。
北京-喜(-) 16:54:19
這個看標的 質量和配比了
北京-陰空(-) 16:54:39
不是打算兩邊切割成同樣數量嗎
北京-喜(-) 16:54:44
會不會導致 資金饑餓,不達標, 做的越細,結果越好. 我原來的思路是 ,假如資金是3段, 那么針對具體的標的,每個段投標的時候,只允許它最多投到1/3。 剩下的2/3預留給另外2個段.
北京-陰空(-) 16:57:05
你看下我這個圖,這樣是否會導致資產分段之后,每個段都只有最優先的一部分能夠投出去呢
北京-喜(-) 16:59:28
這個和你整體當做一段 問題是一樣的, 分段是提高程序效率,不是質量
, 所以,會希望把整體排序來保證優先投遞質量,需要額外細化對標的做權重, 對錢做權重2個之間如果匹配,做個規則
北京-陰空(-) 17:00:30
滿足規則成交是吧
北京-喜(-) 17:00:32
各自的權重模型和匹配規則,未來都是不斷優化的
北京-陰空(-) 17:01:54
那有可能b投了一個后,因為不滿足規則。 只有a段在一直投標了是吧。如果每個段都沒有滿足。
北京-陰空(-) 17:01:58
在降低標準。。
北京-喜(-) 17:02:17
這個就是饑餓的情況, 要么給每個段都留點餅, 這個是指的,對于一個標的,不允許1個段吃完, 要么就是把標的分一分段,每個段內的質量基本差不多, 然后段對段去投, 段內的質量,你需要量化的,某個回報率明顯缺失(被投完),是需要補的,或者重排
北京-陰空(-) 17:06:19
兩個隊列分段都盡量保持質量均勻嗎
北京-陰空(-) 17:08:53
有個地方我覺得是有問題的。 分詞a,b,c三段,三段分別投遞。 然后a段普遍其實優先級都大于b如果每個段投遞的都是相當數量的,肯定是不行。 所以要有規則。b段不滿足的話,就只允許a段投遞,之后再降低規則。 但是假如你降低規則后,有新的滿足高級規則的進來了。 這個就有可能一直沉著了。
北京-喜(-) 17:09:57
北京-陰空(-) 17:15:44
好多了。 喜神的字和我風格好像啊。。
北京-喜(-) 17:16:16
新數據來,是計算,然后加入資源池, 段區對接業務,資源不足,跟中間的管理區申請
北京-陰空(-) 17:17:06
兩個隊列都這么處理。 然后分值一樣的區間進行撮合交易是吧。
北京-喜(-) 17:17:33
分值這個 按照業務了, 不一定是一對一, 同一個標的 基本是什么分值是固定的, 錢不是,因為錢被拆了, 當然標的也可以變啊, 比如同比下,標的可以是2個分值,
北京-陰空(-) 17:19:09
恩,因為我擔心段二整體都比段一差, 結果段二查的部分給投光了,所以考慮分值相近的部分去撮合。
北京-喜(-) 17:19:27
所以優化, 不斷優化
北京-陰空(-) 17:20:24
優化即指打分的模型,也指兩個隊列的撮合規則是吧。
北京-喜(-) 17:21:32
對, 新資源是不是可以入段,取決于段內現狀, 出現空缺,去向資源層申請,或者資源層監控, 有資源就補位
北京-陰空(-) 17:22:29
喜神非常感謝。 感覺有了一個整體思路。 以我對公司的了解。。這么復雜的方式公司肯定不會采用的。。。。我自己嘗試練習下.
北京-喜(-) 17:22:34
資源沒有。質量斷層之后,可能需要重新分, 只有重新分的時候,才需要鎖資源。單純的增量入隊入段,是不需要的
北京-陰空(-) 17:23:35
資源層監控是指起個job去監控每個段位數據的減少是嗎
北京-喜(-) 17:23:47
是的
北京-陰空(-) 17:24:49
這個圖,兩邊應該都是一樣的是吧
北京-喜(-) 17:25:06
是的, 錢端,計算過程多, 沒被投一次 肯定要重新計算一次
北京-陰空(-) 17:25:38
我自己抽空寫一下,寫成功了的話,拿數據跑一下,如果真的性能比數據庫好,領導應該會采用。
北京-喜(-) 17:25:49
數據庫是另外一個事
北京-陰空(-) 17:25:55
是的,放回去需要重算。重新放回是放回資源層,還是放回哪里
北京-喜(-) 17:27:40
這個看你的入隊策略, 允不允許插隊、還是天維度做完即可, 這里也是可以細化的
北京-陰空(-) 17:30:10
感覺每個段里面不同分值區間和另一個隊列里的進行匹配好麻煩。。既要考慮盡可能讓高分去投高分。。又要避免高分的一直停著沒有投出去。。
北京-喜(-) 17:30:54
可以只投一部分, 下一次他的分值就變了, 這個是前面提到的 是不是預拆:6% 7% 8% 各來1W, 這樣是參差不齊都有
北京-陰空(-) 17:32:13
你這個方案把錢也拆了是吧。
北京-喜(-) 17:32:21
我沒拆錢, 這個是分層 和 匹配, 整體還比較粗 實現不了細粒度的投遞質量
北京-喜(-) 17:33:26
這個重分配的那個,假如這個是錢, 回來的時候,你可以讓他重新排隊,就是4那個線。 也可以插隊,就是5那個線, 對于錢,假如現在得分是80, 你可以拆成 70 80 90。 假如是70 ,你可以拆成60 70 80。 假如是90,你可以拆成80 90 100, 80的話,就是好壞都有,70的話就是2個壞的1個中的。 90的話就是1個中的2個好的
北京-陰空(-) 17:36:59
不會有這種情況嗎
北京-喜(-) 17:37:22
會的, 這個時候標的端 要補標的, 沒有可用標的,就要重新分配, 重新分配還不行,那你只能接受了
北京-陰空(-) 17:38:06
整體重排嗎
北京-喜(-) 17:38:11
這個情況就是資產端與標的端 對不齊. 不用, 改分段規則即可, 從中間往右側去的時候,你可以理解成有個shard方式
北京-陰空(-) 17:39:11
原本段一匹配段一改成 段二匹配段一這種是嗎
北京-喜(-) 17:39:24
這個不好, 最好是自治
image.png
北京-喜(-) 17:39:59
在這里解決, 以這個框為例, 右側段內的標的,都是左側資源內的,是關聯的, 所以你可以清空右側段, 重新分段, 按照分值 和 分值內的標的數目,決定如何分.
北京-陰空(-) 17:41:23
懂了應該均勻分布。 如果是正好匹配剩余幾個的情況呢? 比如,資產端段1 100分的有10個, 標的的段1有9個。
北京-喜(-) 17:43:00
理論是看你的積分規則,你怎么積分的,基本決定標的能不能被投, 這個不是啊, 是錢數啊, 不是這個數量
北京-陰空(-) 17:43:34
我是說最后撮合的時候。
北京-喜(-) 17:43:35
是錢的total值, 你也可以作為積分的計算因子加進來, 積分 -> 分值, 名詞對齊下, 你也可以引入批次的概念。 一個批次投完之后(段內完成一次),重新計算標的分值,來解決標的和資產的對齊關系
北京-陰空(-) 17:49:07
每個分數段的標的是一定會小于資產的。
北京-喜(-) 17:50:03
那你們不是負債了么, 還是有資產端的一部分優勢產品,內部投,沒開放給用戶
北京-陰空(-) 17:51:19
資產就是用戶投資來的錢。 資產是債權。債權一般是少于資金的。
北京-喜(-) 17:52:01
那你需要拿到一個數值, 這個負債會影響 資產和標的如何對接, 所以需要有個量化的數字 ,然后整體的計算和分配模型,一直保持在負債區間內,那么就是個好策略
廣州-小護士<-> 18:25:03
今天沒看懂喜神的分享
北京-喜(-) 18:34:52
簡單說:源數據 -> 預計算 -> 實際用 ,分了這三層(每一層都有自己的資源池,資源不足,跟上一級要), 這樣資源就是隔離的了, 極端最壞情況下,場景會回退到不分層,只有1個層的情況下的效率. 可以拿多級緩存來比對。每層緩存放的是不同維度的數據,上一級緩存沒有數據的時候,跟下一級要,都沒有,最后從DB拿。
最壞情況是,緩存全失效,需要重新從DB向各個緩存預熱(計算、處理、刷存儲)。除了這個情況,其他都算健康的。
所以比只有一個數據源(DB)效率要好很多(分層隔離、獨立計算、獨立邏輯)
北京-陰空(-) 18:53:31
喜神。。你這樣解讀感覺太震撼了。。。剛才拿外賣的時候有個想法。能不能,從計算層拿固定數額的到使用層。 先從頭部取。 然后從標的隊列去對應的數量。 這樣可以減少撮合時候的不匹配。
北京-喜(-) 18:56:31
可以的。流量、流速都可以控制, 質量、匹配規則 也可以, 無非是哪里做厚哪里做薄的事
北京-陰空(-) 18:58:37
再問個low的問題。這樣比數據庫order by, 好在哪里呢
北京-喜(-) 19:00:40
資源隔離的, 資源不隔離,就有競爭問題,你的這個場景
北京-陰空(-) 19:03:31
公司打算單線程做。 所以,可能沒有考慮競爭問題
北京-喜(-) 19:04:04
因為元數據不是元數據, 源數據不是元數據, 無法直接用, 要排序 計算 分配
北京-陰空(-) 19:04:54
我們現在的模型是可以的。 我理解排序計算分配是為了更加高效。 我懂了你的意思了, 源數據是不能直接使用。沒有排序。 所以,他們加入到數據庫 , 通過數據庫orderby了
北京-喜(-) 19:05:36
是的, 所以你需要保護他
北京-陰空(-) 19:06:08
所以,直接用數據庫缺點是什么?
北京-喜(-) 19:06:44
慢是一方面, 取決于排序復雜度和存量數據大小, 另外還有個問題是風險, DB掛了的話,上層其實可以有次優解, 把自己的資源池耗空 能抗一會業務, 不從DB補位標的而已, 另外架構上 建議讀寫分離,這個有空再說.
北京-喜(-) 19:10:50
你的排序和計算 都是讀邏輯, 但是放在源庫上了, 源庫做寫業務比較好,比如實際的投的結果和新標的入庫
北京-陰空(-) 19:10:43
明白
北京-喜(-) 19:13:53
大數據計算 好像有個模型并行和數據并行?
北京-陰空(-) 19:13:59
是的。
北京-喜(-) 19:14:15
模型并行那個適合你的場景好像. 思路是類似, 三層模型. 并行 隔離.