文章版權由作者李曉暉和博客園共有,若轉載請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/
1.背景
1.1傳統MySQL+ Memcached架構遇到的問題
MySQL本身是適合進行海量數據存儲的,通過Memcached將熱點數據加載到cache從而加速訪問,很多公司目前都采用這樣的架構,但隨着業務數據量和訪問量的持續增長,我們遇到了很多問題:
a.MySQL需要不斷進行拆庫拆表,Memcached也需不斷跟着擴容,擴容和維護工作占據大量開發時間。
b.Memcached與MySQL數據庫數據一致性問題。
c.Memcached數據命中率低或宕機,大量訪問直接穿透到DB,MySQL無法支撐。
d.跨機房cache同步問題。
為解決以上問題,我們開始選擇用Redis來替代Memcached。
1.2Redis簡介
Redis是一種典型的NoSQL數據庫服務器,它可以作為服務程序獨立運行於自己的服務器主機。在很多時候,人們只是將Redis視為Key/Value數據庫服務器,但是在目前的版本中,Redis除了Key/Value之外還支持List、Hash、Set和Ordered Set等數據結構,因此它的用途也更為寬泛。Redis的License是Apache License,就目前而言,它是完全免費。
我們經常會將memcached(數據緩存服務器)與Redis來進行對比,因為他們在使用方式上比較相似,而且也均是免費,均使用了內存來進行數據緩存。但是它們之間的最大區別在於memcached只是提供了數據緩存服務,一旦服務器宕機,之前在內存中緩存的數據也將全部消失, memcached沒有提供任何形式的數據持久化功能,而Redis則提供了這樣的功能。第二,Redis提供了更為豐富的數據存儲結構,如Hash和Set等。
項目中經常在如下幾個場景中使用Redis:Session共享,數據采集統計等。
2.Redis環境搭建
2.1下載安裝
Redis對於Linux是官方支持的,安裝和使用參考官網(http://redis.io/download),但是Redis官方是不支持windows的,好在 Microsoft Open Tech group 在 GitHub上開發了一個Win64的版本,項目地址是:https://github.com/MSOpenTech/redis。打開后,直接使用瀏覽器下載或Git克隆即可:
直接雙擊redis-server.exe即啟動一個redis服務實例,但是如果想以windows服務形式運行,需要執行一下命令:
//注冊至服務管理中
redis-server --service-install redis.windows.conf --loglevel verbose --service-name Redis6379
成功后,開啟服務即可:
2.2主從配置
Redis如mysql數據庫一樣,可以支持主從數據庫配置,而且配置方式十分簡單。將原有Redis安裝文件再復制一份,打開Config文件,修改對應slaveof配置即可:
以上面提到的指令注冊服務,運行該從數據庫:
2.3密碼和權限配置
Redis默認是沒有密碼的,為了數據的安全性需要我們自己啟動權限控制和密碼配置等。
2.3.1設置訪問權限
打開config文件,找到bind關鍵字,修改其中綁定的IP即可:
2.3.2設置密碼
同樣打開config文件,找到requirepass關鍵字,將對應部分修改為指定密碼:
注意,如果我們對主數據庫設定了密碼,那么slave數據庫上在監聽主數據庫的配置中也要加上對應的密碼:
2.4Redis可視化管理工具
這里我們使用RedisDesktopManager來管理Redis數據庫。在官網上(https://redisdesktop.com/download)下載完該工具后,本地安裝后連接至數據庫上:
單擊主數據庫文件中的redis-cli.exe,輸入測試命令:
在輸入獲取Value的命令,發現已經成功:
同時,在可視化工具中能看到,主從數據庫中均已同步:
3.Java操作
3.1依賴環境
使用Java操作Redis需要jedis-2.1.0.jar,下載地址:http://files.cnblogs.com/liuling/jedis-2.1.0.jar.zip。
如果需要使用Redis連接池的話,還需commons-pool-1.5.4.jar,下載地址:http://files.cnblogs.com/liuling/commons-pool-1.5.4.jar.zip。
3.2常用據類型使用
Redis中可以存儲各種數據類型,不同數據類型有其使用場景,具體各數據類型的使用在操作文檔中均能查找(http://redisdoc.com/index.html):
這里以幾個常用類型作為介紹。
3.2.1連接
3.2.2String
String是最常用的一種數據類型,普通的key/value存儲都可以歸為此類,value其實不僅是String,也可以是數字:比如想知道什么時候封鎖一個IP地址(訪問超過幾次)。INCRBY命令讓這些變得很容易,通過原子遞增保持計數。
3.2.3List
在Redis中,List類型是按照插入順序排序的字符串鏈表。和數據結構中的普通鏈表一樣,我們可以在其頭部(left)和尾部(right)添加新的元素。在插入時,如果該鍵並不存在,Redis將為該鍵創建一個新的鏈表。與此相反,如果鏈表中所有的元素均被移除,那么該鍵也將會被從數據庫中刪除。List中可以包含的最大元素數量是4294967295。
從元素插入和刪除的效率視角來看,如果我們是在鏈表的兩頭插入或刪除元素,這將會是非常高效的操作,即使鏈表中已經存儲了百萬條記錄,該操作也可以在常量時間內完成。然而需要說明的是,如果元素插入或刪除操作是作用於鏈表中間,那將會是非常低效的。相信對於有良好數據結構基礎的開發者而言,這一點並不難理解。
3.2.4Set
在Redis中,我們可以將Set類型看作為沒有排序的字符集合,和List類型一樣,我們也可以在該類型的數據值上執行添加、刪除或判斷某一元素是否存在等操作。需要說明的是,這些操作的時間復雜度為O(1),即常量時間內完成次操作。Set可包含的最大元素數量是4294967295。
和List類型不同的是,Set集合中不允許出現重復的元素,這一點和C++標准庫中的set容器是完全相同的。換句話說,如果多次添加相同元素,Set中將僅保留該元素的一份拷貝。和List類型相比,Set類型在功能上還存在着一個非常重要的特性,即在服務器端完成多個Sets之間的聚合計算操作,如unions、intersections和differences。由於這些操作均在服務端完成,因此效率極高,而且也節省了大量的網絡IO開銷。
3.2.5Hash
我們可以將Redis中的Hashes類型看成具有String Key和String Value的map容器。所以該類型非常適合於存儲值對象的信息。如Username、Password和Age等。如果Hash中包含很少的字段,那么該類型的數據也將僅占用很少的磁盤空間。每一個Hash可以存儲4294967295個鍵值對。
4.redis的持久化問題
Redis提供了以下幾種持久化方式:
a.RDB持久化:
該機制是指在指定的時間間隔內將內存中的數據集快照寫入磁盤。
b.AOF持久化:
該機制將以日志的形式記錄服務器所處理的每一個寫操作,在Redis服務器啟動之初會讀取該文件來重新構建數據庫,以保證啟動后數據庫中的數據是完整的。
c.無持久化:
我們可以通過配置的方式禁用Redis服務器的持久化功能,這樣我們就可以將Redis視為一個功能加強版的memcached了。
d.同時應用AOF和RDB。
5.Redis與GIS的結合:GEO數據類型
Redis3.2版本中增加了對GEO(地理位置)的支持。目前其提供了以下幾種操作方式:
a.geoadd:增加某個地理位置的坐標。
b.geopos:獲取某個地理位置的坐標。
c.geodist:獲取兩個地理位置的距離。
d.georadius:根據給定地理位置坐標獲取指定范圍內的地理位置集合。
e.georadiusbymember:根據給定地理位置獲取指定范圍內的地理位置集合。
f.geohash:獲取某個地理位置的geohash值。
因為其面向的為主流互聯網環境,所以其支持的地理坐標系指定為WGS84坐標系,其中的geohash編碼算法與我在之前的博客中所提到的一致:WebGIS中GeoHash編碼的研究和擴展(http://www.cnblogs.com/naaoveGIS/p/5164187.html)。除了我們自己寫代碼完成該算法,也有已經開源封裝好的源碼:https://github.com/kungfoo/geohash-java。
-----歡迎轉載,但保留版權,請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/
如果您覺得本文確實幫助了您,可以微信掃一掃,進行小額的打賞和鼓勵,謝謝 ^_^