[問題] 多執行緒伺服器設計問題

看板C_and_CPP (C/C++)作者 (靜雨澪)時間7年前 (2019/03/14 22:53), 7年前編輯推噓4(4021)
留言25則, 7人參與, 7年前最新討論串1/1
版上各位先進好: 小弟我目前在設計多執行緒的伺服器上遇到效能瓶頸, 底層的Socket Server是用Boost::Asio, 單純用single io_service & multiple thread的架構處理效能還不錯, 但目前系統上都會需要封包指令是要將某個index要對應到某個session, 所以只好在accept時把index跟session存入到map中,這時就需要使用lock去做保護, 因為加了這個lock導致在一秒內如果是上萬的連線數要aceept延遲就會提高, 後面開始run的過程中因為我使用的是shared_mutex, 所以對map純讀(shared_lock)感覺效能還可以。 如果是單純讀寫分離的Queue還可以用boost::lockfree去處理, 但遇到真的架構上就需要有一個map,這種情況就不知道怎麼優化它, 想問版上的各位先進有什麼設計方向可供我參考,謝謝。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 122.117.102.47 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1552575225.A.E28.html

03/14 23:04, 7年前 , 1F
問題在於你為什麼會設計成一秒需要 accept 上萬次吧
03/14 23:04, 1F
老闆的需求 QQ

03/15 00:27, 7年前 , 2F
vector 存 index + session, 就不用lock ?
03/15 00:27, 2F
index是int64_t, 直接先配置好vector好像有點太大, 還有session連線斷線的問題勢必要lock

03/15 02:30, 7年前 , 3F
白說這問題打成英文上 stackoverflow 問應該會比較好
03/15 02:30, 3F

03/15 02:30, 7年前 , 4F
坦白說
03/15 02:30, 4F

03/15 02:35, 7年前 , 5F
目前可以知道的資訊有點少,也許你目前這層可以複製 N 個
03/15 02:35, 5F

03/15 02:36, 7年前 , 6F
docker containers 去跑起來,然後最前端再擋個類似負載
03/15 02:36, 6F

03/15 02:36, 7年前 , 7F
平衡的東西,譬如根據 index % N 的值來轉發封包給對應的
03/15 02:36, 7F

03/15 02:38, 7年前 , 8F
container 處理這個 request。這種解法比較偏向架構解,
03/15 02:38, 8F

03/15 02:39, 7年前 , 9F
考量將來 scalability 的話你早晚要做類似的工。如果你只
03/15 02:39, 9F

03/15 02:40, 7年前 , 10F
打算先集中在程式解,那試試看起多個 io_context 有沒有
03/15 02:40, 10F

03/15 02:40, 7年前 , 11F
什麼用吧。
03/15 02:40, 11F

03/15 02:41, 7年前 , 12F
io_service 在新版 boost 已經 deprecated 了。
03/15 02:41, 12F

03/15 02:47, 7年前 , 13F
簡單講的話目的都是先增加你程式的入口數,然後把原本因
03/15 02:47, 13F

03/15 02:48, 7年前 , 14F
為 lock 變成瓶頸的單一大資料塊拆分成多個。
03/15 02:48, 14F
其實就是GameServer的入口, index就是玩家資料在DB的ID, 資料轉到其他Service去處理完後,再丟回給GameServer傳給對應的玩家, 所以它才需要一個ID跟Session的Map, 目前的確我是有設計類似加開分流的概念去處理這件事, 但不同的Server的遊戲邏輯是不互通的, 所以還是想增加單個伺服器的承載量. ※ 編輯: klsdf (122.117.102.47), 03/15/2019 07:10:46

03/15 12:13, 7年前 , 15F
這種東西連線建立以後就不需要再反覆 accept 了,每秒上
03/15 12:13, 15F

03/15 12:14, 7年前 , 16F
萬次的連線需求是怎麼出現的?畢竟不是 http 這種連完
03/15 12:14, 16F

03/15 12:14, 7年前 , 17F
一次就斷一次的連線型態。
03/15 12:14, 17F

03/15 14:32, 7年前 , 18F
int64_t你也用不完呀 實務上你抓個可以涵蓋峰值的大小
03/15 14:32, 18F

03/15 14:35, 7年前 , 19F
配就好了 而且vector要鎖最起碼可以個別鎖呀
03/15 14:35, 19F

03/16 07:29, 7年前 , 20F
每一條連線有平均與最大的耗用資源量,同時估計一下resp
03/16 07:29, 20F

03/16 07:29, 7年前 , 21F
onse time/CPU時間,找出一臺機器的服務上限,對應的sess
03/16 07:29, 21F

03/16 07:29, 7年前 , 22F
ion數量一次配置完,連線對應固定的索引值就不用map了
03/16 07:29, 22F
主要是索引值是玩家的編號 即使知道目前的帳號數量pre-allocate 但對新註冊的帳號沒有用, 不過使用vector跟隨機存取的想法我可能可以多想一下 ※ 編輯: klsdf (122.117.102.47), 03/17/2019 00:08:03

03/17 01:02, 7年前 , 23F
寫個load balancer
03/17 01:02, 23F

03/17 19:58, 7年前 , 24F
SO_REUSEPORT https://goo.gl/4rxJfr 參考看看
03/17 19:58, 24F

03/17 20:09, 7年前 , 25F
若非得查表可考慮使用 tbb::concurrent_unordered_map
03/17 20:09, 25F
文章代碼(AID): #1SYchvue (C_and_CPP)
文章代碼(AID): #1SYchvue (C_and_CPP)