用序列化的方式保存簡單的數據類型之積分查詢系統的建設

最近有個小活,是作一個積分查詢接口,因爲積分系統是內部系統且沒法鏈接外網,因此數據只能經過導出-導入的方式加入到積分查詢接口的小系統中。java

看到這裏,你確定認爲這沒什麼呀,但我把如下條件列出後,你的想法可能會改變一些:mysql

一、數據一共有50萬條左右;sql

二、數據的導出只能用文本文件;數據庫

三、積分接口的數據庫是mysql;瀏覽器

四、原卡庫的數據庫是mssqlsser2008;緩存

五、要保證查詢速度;tomcat

六、每日更新的數據大概有20000條左右;服務器

七、積分接口所在服務器不容許遠程鏈接數據庫和遠程登陸,只能經過積分接口系統完成數據的導入;多線程

八、服務器配置不高。測試


以上就是要求,根據需求,我先測試如何將這幾十萬條數據導入到數據庫;首先存放數據的文本文件有10MB大小,初步我想的是如何將這個文件中的KV鍵值對轉換成數據庫能識別的sql語句,因而,我用了一下午的時間完成文件內容的轉換... ... 或許你會問,怎麼會用了一下午呢?應該很快吧?我要說編碼的時間確實沒用多少,但轉換可就費時了,整個轉換過程整整用了一整個下午!!!

試過才知道該方法不可行,那就分割數據文件吧,而後用多線程同時執行。我先把數據文件分割成沒20000條一個文件,而後用線程分別轉換,此次轉換效果較第一次有很大改善,但依然用了將近一個小時。莫非java對字符串的處理這麼費時?因而百度、google,沒有找到有用的解釋,好吧,那繼續吧。

轉換完成的sql文件有24MB大小,當我看到這個文件時,我預料到數據導入的速度也不會快。不過我仍是執行了數據導入,結果我不想多說,總之,很慘。

慘歸慘,不過數據好在都有了,那就作查詢接口吧。輕車熟路,很快,一個帶傳輸參數加密(其實就是編碼)、驗證身份和數據緩存的接口完成了,本地部署測試,一切正常,而後上傳到服務器,當天一切正常。到次日早上,我把新導出的文本文件(19000多條數據)上傳到服務器並執行數據的轉換和導入操做,經過日誌查詢頁面,感受系統響應速度奇慢,大約運行了兩個小時後,頁面中止響應,查看服務器狀態,提示內存溢出,服務器配置自己就不高,我還在一個tomcat下部署了N個應用,看來撐不住了。

這個時候我有點心虛了,怎麼辦?不能天天搞這麼個東西呀?在這後面我想了不少辦法,如把文件2sql轉換的工做放在前臺用JS來實現,結果瀏覽器掛了;用lucene生成索引吧,沒法完成有效的查詢;... ...

最終,我想不行就試試serizable接口吧,把數據導入到繼承了serizable接口的對象中,而後序列化到磁盤中,用的時候緩存到內存中,查詢也快;通過將近一個小時的改造,除了最初的文件上傳還保留外,其餘的都改造了。改造完成的系統,文件上傳到服務器端後,再也不保存爲文件,而是經過stream的方式讀取數據並進行KV鍵值對的分離,而後存入MAP對象中。KV分離完成後,先將Map對象賦值給緩存供接口查詢用,而後將map保存到磁盤,以便容器重啓後能夠從新導入數據,也至關於作了數據的持久化。

因爲天天都有更新的數據,而這些數據中可能有須要將map中已有Key的value更新的,也可能有新加入的,這也正好是map的特性。

到目前爲止,系統運行穩定,查詢直接從內存中完成,且能經受住高強度負載,基本滿意,但數據的轉換速度仍是有點慢,雖然已經使用了線程。

總結:作應用的一個習慣,就是掛載數據庫,其實在作一些不復雜的且數據量不大的應用時,徹底能夠考慮序列化。不過序列化也有一些侷限性,如某些數據對象是沒法作序列化的。

相關文章
相關標籤/搜索