在一些大數據處理中,我們需要用到IP地址查詢,一般為了查詢一個IP屬於哪個地址,我們通常需要根據一個IP數據庫來查詢,網絡上比較常用的IP庫是純真IP數據庫。IP數據庫里面的記錄一般存儲方式為IP的開始和結束的數字段,比如 "221.179.172.1-221.179.175.254 中國移動/北京市" 我們通常把IP轉換為長整型存儲為"3719539713,3719540734,中國移動,北京市",我們查詢的時候就可以 先把IP轉換為長整型,然后去大於開始,小於結束這個條件去查詢,但是一般IP數據庫都有幾十萬條數據,我們去這樣查詢,即使建立索引或者全部放到內存查詢,效率還是不太高,通常1秒查詢幾百次,看上去效率已經很高了,但是試想如果我要查詢1億次,就需要幾百個小時,在做大數據量數據處理的時候,這個速度還是很慢的。
為了提高查詢速度,我們引入redis,redis是目前熱門的Nosql數據庫,很多大的公司都在用,具體的用法大家可以查查資料,redis中有一種數據結構是有序集合 sortset,我的IP數據庫可以轉化為sortset存儲, 一個sortset中存儲所有的IP記錄(所有的IP地址區間不允許重復),結構為value中存儲IP的開始(長整型),結束(長整型),省份等,分別依照逗號隔開,score中存放的是IP的結束值(長整型)
舉例為
value score
1,5,中國移動,北京市 5
10,20,中國聯通,上海市 20
比如我們查詢一個IP,IP轉化為長整型的數字為 2,然后我們查詢的時候就通過sortset 的zrangebyscore ranges 2 +inf LIMIT 0 1 這樣我們就查詢出來大於2的第一條記錄,這樣我們查詢出來記錄為 “1,5,中國移動,北京市” 然后我們在判斷一下 我們要查詢的地址在不在 1,5之間,2在1,5之間,所以查出來了2對應的IP地址為中國移動北京市,再比如我們要查詢的IP地址數字為 8,通過zrangebyscore ranges 8 +inf LIMIT 0 1 我們查詢到了 10,20,中國聯通,上海市,但是8不在10,20之間,所以查詢不到此IP對應的地址。
通過這個思路,我寫了個測試程序,100000次查詢,IP記錄172738條,耗時5.2秒左右,差不多一秒鍾兩萬次,我在windows下測試的,機器配置(固態硬盤)為

redis記錄:

程序運行結果

當然我這個模擬測試,不是真實的IP地址,如果換成真實的IP,差距多大,大家自行驗證。
參考
https://groups.google.com/forum/#!topic/redis-db/lrYbkbxfQiQ
文章出處:http://www.cnblogs.com/weiguang3100/
在線工具:http://51tools.info
.NET 開發交流關注微信公眾號
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
