OnlineJudge系統的判題數據,用資料庫存、用文件存哪種比較好?

分析了一下Hustoj,裡面是把所有的判題數據寫成.in和.out文件,並且存在/home/judge/data下面。。。

話說文件磁碟io的瓶頸不是挺大的么?為啥不直接存儲在資料庫裡頭?甚至用memcache?用文件存儲的設計有啥好處?

話說oj裡面的輸入輸出文件通常比較大,平均每道題50k左右。題目多了的話很輕易上G。。。但是條目不多(幾千條的樣子,如果為了可擴展性考慮可能有幾萬條)。


其實我心目中的一個理想的OJ是這個樣子的

server1 提供web服務(nginx+php或者python或者其它)

server2 提供一個http(nginx)的靜態伺服器 存放數據

server3 是資料庫

server4 弄個redis作為緩存兼做隊列

server5是判題機 可以放n台 從server4的redis隊列里拉取所有的待評測的任務 從資料庫中取出任務詳情包括代碼 從server2 的nginx上把數據包拉下來 評測完了之後更新資料庫

以上一堆機器均可合併或者拆分成多台

對於較大流量(網路賽這種) 多加點判題機 頁面盡量緩存住 隨便你怎麼刷新都不用擔心

應對突發流量現在大家不都是先放開pdf下載然後到時間點了公開密碼嗎?

這樣子的系統下面 磁碟IO從來都不是一個需要擔心的問題

整個系統最大的資源消耗點其實是CPU 你一個提交2秒超時你就按它佔掉2秒一個CPU核心來算 根據你的提交數量和比賽時長大概也能算出來要多少台機器多少個CPU了吧 對於一個2秒鐘都要花掉的事情 你消耗個0.1秒在磁碟IO上面又有什麼影響呢,我花0.2秒鐘從同一個區域網內下載一個100M的數據包又能怎樣呢,況且我還可以在評測機上cache一下?

這塊去優化掉實際上並不對整體系統的可用性造成多好的影響,其實是一點用都沒有。

我現在管理的一套類似架構的系統在峰值的時候能有4000人在線 全部的動態的大概每秒300+的請求量 所以不用擔心這個樣子撐不住

redis和nginx都是在別的東西不是瓶頸的時候一秒鐘處理能力上萬的東東 怕個啥。

被各位吐槽的HUSTOJ的最初版本是我寫的 設計上的不周之處 請大家多多包涵 我就是個大菜鳥 這個事情大家默默的知道就好了 至於到處宣揚嘛 隨意吧 @.@

btw: 某某大神說過 過早的優化是萬惡之源

btw2: 話說當年寫那堆渣一樣的代碼的時候小弟才20歲出頭 這尼瑪一轉眼都快30了


測試數據動輒幾十兆,放資料庫的話,效率真的未必高,反而可能會增加其他數據的碎片化。

Linux幾乎所有未使用的內存均用於磁碟緩存,經常讀取的文件內容很容易緩存,真的內存夠大,用個軟連接連到內存檔/dev/shm,就是冷起需要加個腳本。

HUSTOJ有OJ_SHM_RUN開關,打開後運行時目錄是全部放在內存中的。

此外HUSTOJ支持HTTP模式的分散式判題,隨時可以動態增加新的判題機。

至於效率問題,反正是開源的,真的在乎,可以自己注釋掉ptrace的相關代碼行,效率就上來了,安全自然會相應的變弱,正式比賽應該不會有人故意黑,因為都是實名。

因為支持HTTP模式的分散式,所以判題放在虛擬機還是Docker都是部署層面的問題。

-----------------------------------

以上,洗地


存在哪裡都是磁碟IO,不過數據取出來以後是否緩存,如何緩存還是值得探討的。如果是windows操作系統的話還會自帶磁碟緩存,linux我就不知道了。

說真心話hustoj的代碼就是一坨渣,作者根本就不關心運行效率(其實也不太懂),可能是學校裡面的老師沒有這方面的動力吧。


judger不是伺服器主要壓力。。。

OJ壓力一般主要在web伺服器和資料庫。


我們學校OJ也是數據用文件存儲,不過一個OJ最多也就幾千道題,這個倒不是問題,關鍵是我們OJ用戶提交的代碼也是文件存儲!百萬條數據呢,就一個一個文件在一個目錄里,你要是敢ls一下就死定了。

最近在開發vjudge,所有數據全部存資料庫,用的mongodb,等做完也得考慮下優化了。


你知道嗎,其實這個問題應該(at)杭電oj現任2個管理員何陽和胡傑,還有最關鍵的貢獻者linle 233333,論如何用單伺服器撐起在網路賽/多校壓力下的網頁+資料庫+評測壓力。

目前的話,據我了解,其實測試數據到底存哪裡好也沒有定論,但是目前杭電oj的做法是,BestCoder的hack數據存在資料庫里(上限1MB每條),其他的以文件形式保存在文件夾里。

題主的「oj裡面的輸入輸出文件通常比較大」這個發現是對的,但是「平均每道題50k左右」就有點錯的離譜了,至少不是現在的流行趨勢……

如果不是根據1個輸入就得到結果的,而是給出字元串/一個圖/一大組信息等等,為了卡掉正確性就沒有的,時間/空間效率不夠優的代碼,不是50KB的輸入文件就能輕鬆秒殺的,一個完整的終測大文件少說也得1MB,5~10MB已經習以為常(像我這種出個水題也要讓標程跑個100~200ms才罷休的,數據不超過5MB都擔心卡不掉效率糟糕的),甚至會有突破50MB/100MB的情況,這個時候存資料庫,好大一個查詢結果啊,傷害不要太高……


最近我在寫Windows下的評測內核,我就回答一下我所知道的吧。

最主要的一點:評測需要運行一個進程,把進程的輸入輸出重定向到文件,使用緩存還需要把緩存里的內容保存到文件進行評測。

第二點:我們使用的評測系統一般沒有考慮分散式評測,使用緩存沒有優勢。


推薦閱讀:

如何理解資料庫的內部一致性和外部一致性?
剛開始學習資料庫對資料庫概念一竅不通。?
如何系統學習 MySQL?
個人網站,資料庫如何設計存儲富文本文章比較好?
想真正從基礎到深入地學習資料庫,但是市面上的數據過多,有什麼好的書籍,網站嗎?

TAG:資料庫 | 系統架構 | OnlineJudge | 資料庫設計 | ACM競賽 |