redis緩存數據庫??
緩存數據庫介紹
NoSQL(NoSQL = Not Only SQL ),意即“不僅僅是SQL”,泛指非關系型的數據庫,隨著互聯網web2.0網站的興起,傳統的關系數據庫在應付web2.0網站,特別是超大規模和高並發的SNS類型的web2.0純動態網站已經顯得力不從心,暴露了很多難以克服的問題,而非關系型的數據庫則由於其本身的特點得到了非常迅速的發展。NoSQL數據庫的產生就是為了解決大規模數據集合多重數據種類帶來的挑戰,尤其是大數據應用難題。
NoSQL數據庫的四大分類
鍵值(Key-value)存儲數據庫
這一類數據庫主要會使用到一個哈希表,這個表中有一個特定的鍵和一個指針指向特定的數據。Key/value模型對於IT系統來說的優勢在於簡單、易部署。但是如果SBA只對部分值進行查詢或更新的時候,Key/value就顯得效率低下了。[3] 舉例如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB. 列存儲數據庫。NoSQL數據庫的四大分類表格分析
redis
介紹
redis是業界主流的key-value nosql 數據庫之一。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步。
Redis優點
-
異常快速 : Redis是非常快的,每秒可以執行大約110000設置操作,81000個/每秒的讀取操作。
-
支持豐富的數據類型 : Redis支持最大多數開發人員已經知道如列表,集合,可排序集合,哈希等數據類型。
這使得在應用中很容易解決的各種問題,因為我們知道哪些問題處理使用哪種數據類型更好解決。 -
操作都是原子的 : 所有 Redis 的操作都是原子,從而確保當兩個客戶同時訪問 Redis 服務器得到的是更新後的值(最新值)。
- MultiUtility工具:Redis是一個多功能實用工具,可以在很多如:緩存,消息傳遞隊列中使用(Redis原生支持發布/訂閱),在應用程序中,如:Web應用程序會話,網站頁面點擊數等任何短暫的數據;
安裝Redis環境
要在 Ubuntu 上安裝 Redis,打開終端,然後輸入以下命令:1 $sudo apt-get update 2 $sudo apt-get install redis-server這將在您的計算機上安裝Redis
啟動 Redis
1 $redis-server
查看端口
1 netstat -tulnp
查看 redis 是否還在運行
$redis-cli
這將打開一個 Redis 提示符,如下圖所示:
redis 127.0.0.1:6379>
在上面的提示信息中:127.0.0.1 是本機的IP地址,6379是 Redis 服務器運行的端口。現在輸入 PING 命令,如下圖所示:
redis 127.0.0.1:6379> ping
PONG
這說明現在你已經成功地在計算機上安裝了 Redis。
Python操作Redis
1 sudo pip install redis 2 or 3 sudo easy_install redis 4 or 5 源碼安裝 6 7 詳見:https://github.com/WoLpH/redis-py
在Ubuntu上安裝Redis桌面管理器
要在Ubuntu 上安裝 Redis桌面管理,可以從 http://redisdesktop.com/download 下載包並安裝它。
Redis 桌面管理器會給你用戶界面來管理 Redis 鍵和數據。
操作
1. String操作
redis中的String在在內存中按照一個name對應一個value來存儲。如圖:
set(name, value, ex=None, px=None, nx=False, xx=False)
1 在Redis中設置值,默認,不存在則創建,存在則修改 2 參數: 3 ex,過期時間(秒) 4 px,過期時間(毫秒) 5 nx,如果設置為True,則只有name不存在時,當前set操作才執行 6 xx,如果設置為True,則只有name存在時,崗前set操作才執行
setnx(name, value)
1 設置值,只有name不存在時,執行設置操作(添加)
setex(name, value, time)
1 # 設置值 2 # 參數: 3 # time,過期時間(數字秒 或 timedelta對象)
psetex(name, time_ms, value)
1 # 設置值 2 # 參數: 3 # time_ms,過期時間(數字毫秒 或 timedelta對象)
mset(*args, **kwargs)
1 批量設置值 2 如: 3 mset(k1=‘v1‘, k2=‘v2‘) 4 或 5 mget({‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘})
get(name)
獲取值
mget(keys, *args)
1 批量獲取 2 如: 3 mget(‘ylr‘, ‘wupeiqi‘) 4 或 5 r.mget([‘ylr‘, ‘wupeiqi‘])
getset(name, value)
1 設置新值並獲取原來的值
getrange(key, start, end)
1 # 獲取子序列(根據字節獲取,非字符) 2 # 參數: 3 # name,Redis 的 name 4 # start,起始位置(字節) 5 # end,結束位置(字節) 6 # 如: "武沛齊" ,0-3表示 "武"
setrange(name, offset, value)
1 # 修改字符串內容,從指定字符串索引開始向後替換(新值太長時,則向後添加) 2 # 參數: 3 # offset,字符串的索引,字節(一個漢字三個字節) 4 # value,要設置的值
setbit(name, offset, value)
1 # 對name對應值的二進制表示的位進行操作 2 3 # 參數: 4 # name,redis的name 5 # offset,位的索引(將值變換成二進制後再進行索引) 6 # value,值只能是 1 或 0 7 8 # 註:如果在Redis中有一個對應: n1 = "foo", 9 那麽字符串foo的二進制表示為:01100110 01101111 01101111 10 所以,如果執行 setbit(‘n1‘, 7, 1),則就會將第7位設置為1, 11 那麽最終二進制則變成 01100111 01101111 01101111,即:"goo" 12 13 # 擴展,轉換二進制表示: 14 15 # source = "武沛齊" 16 source = "foo" 17 18 for i in source: 19 num = ord(i) 20 print bin(num).replace(‘b‘,‘‘) 21 22 特別的,如果source是漢字 "武沛齊"怎麽辦? 23 答:對於utf-8,每一個漢字占 3 個字節,那麽 "武沛齊" 則有 9個字節 24 對於漢字,for循環時候會按照 字節 叠代,那麽在叠代時,將每一個字節轉換 十進制數,然後再將十進制數轉換成二進制 25 11100110 10101101 10100110 11100110 10110010 10011011 11101001 10111101 10010000 26 -------------------------- ----------------------------- ----------------------------- 27 武 沛 齊
*用途舉例,用最省空間的方式,存儲在線用戶數及分別是哪些用戶在線
getbit(name, offset)
1 # 獲取name對應的值的二進制表示中的某位的值 (0或1)
bitcount(key, start=None, end=None)
1 # 獲取name對應的值的二進制表示中 1 的個數 2 # 參數: 3 # key,Redis的name 4 # start,位起始位置 5 # end,位結束位置
strlen(name)
1 # 返回name對應值的字節長度(一個漢字3個字節)
incr(self, name, amount=1)
1 # 自增 name對應的值,當name不存在時,則創建name=amount,否則,則自增。 2 3 # 參數: 4 # name,Redis的name 5 # amount,自增數(必須是整數) 6 7 # 註:同incrby
incrbyfloat(self, name, amount=1.0)
1 # 自增 name對應的值,當name不存在時,則創建name=amount,否則,則自增。 2 3 # 參數: 4 # name,Redis的name 5 # amount,自增數(浮點型)
decr(self, name, amount=1)
1 # 自減 name對應的值,當name不存在時,則創建name=amount,否則,則自減。 2 3 # 參數: 4 # name,Redis的name 5 # amount,自減數(整數)
append(key, value)
1 # 在redis name對應的值後面追加內容 2 3 # 參數: 4 key, redis的name 5 value, 要追加的字符串
2. Hash操作
hash表現形式上有些像pyhton中的dict,可以存儲一組關聯性較強的數據 , redis中Hash在內存中的存儲格式如下圖:
hset(name, key, value)
1 # name對應的hash中設置一個鍵值對(不存在,則創建;否則,修改) 2 3 # 參數: 4 # name,redis的name 5 # key,name對應的hash中的key 6 # value,name對應的hash中的value 7 8 # 註: 9 # hsetnx(name, key, value),當name對應的hash中不存在當前key時則創建(相當於添加)
hmset(name, mapping)
1 # 在name對應的hash中批量設置鍵值對 2 3 # 參數: 4 # name,redis的name 5 # mapping,字典,如:{‘k1‘:‘v1‘, ‘k2‘: ‘v2‘} 6 7 # 如: 8 # r.hmset(‘xx‘, {‘k1‘:‘v1‘, ‘k2‘: ‘v2‘})
hget(name,key)
1 # 在name對應的hash中獲取根據key獲取value
hmget(name, keys, *args)
1 # 在name對應的hash中獲取多個key的值 2 3 # 參數: 4 # name,reids對應的name 5 # keys,要獲取key集合,如:[‘k1‘, ‘k2‘, ‘k3‘] 6 # *args,要獲取的key,如:k1,k2,k3 7 8 # 如: 9 # r.mget(‘xx‘, [‘k1‘, ‘k2‘]) 10 # 或 11 # print r.hmget(‘xx‘, ‘k1‘, ‘k2‘)
hgetall(name)
1 獲取name對應hash的所有鍵值
hlen(name)
1 # 獲取name對應的hash中鍵值對的個數
hkeys(name)
1 2 # 獲取name對應的hash中所有的key的值
hvals(name)
1 # 獲取name對應的hash中所有的value的值
hexists(name, key)
1 # 檢查name對應的hash是否存在當前傳入的key
hdel(name,*keys)
1 # 將name對應的hash中指定key的鍵值對刪除
hincrby(name, key, amount=1)
1 # 自增name對應的hash中的指定key的值,不存在則創建key=amount 2 # 參數: 3 # name,redis中的name 4 # key, hash對應的key 5 # amount,自增數(整數)
hincrbyfloat(name, key, amount=1.0)
1 # 自增name對應的hash中的指定key的值,不存在則創建key=amount 2 3 # 參數: 4 # name,redis中的name 5 # key, hash對應的key 6 # amount,自增數(浮點數) 7 8 # 自增name對應的hash中的指定key的值,不存在則創建key=amount
hscan(name, cursor=0, match=None, count=None)
Start a full hash scan with:
HSCAN myhash 0
Start a hash scan with fields matching a pattern with:
HSCAN myhash 0 MATCH order_*
Start a hash scan with fields matching a pattern and forcing the scan command to do more scanning with:
HSCAN myhash 0 MATCH order_* COUNT 1000
# 增量式叠代獲取,對於數據大的數據非常有用,hscan可以實現分片的獲取數據,並非一次性將數據全部獲取完,從而放置內存被撐爆 # 參數: # name,redis的name # cursor,遊標(基於遊標分批取獲取數據) # match,匹配指定key,默認None 表示所有的key # count,每次分片最少獲取個數,默認None表示采用Redis的默認分片個數 # 如: # 第一次:cursor1, data1 = r.hscan(‘xx‘, cursor=0, match=None, count=None) # 第二次:cursor2, data1 = r.hscan(‘xx‘, cursor=cursor1, match=None, count=None) # ... # 直到返回值cursor的值為0時,表示數據已經通過分片獲取完畢
hscan_iter(name, match=None, count=None)
1 # 利用yield封裝hscan創建生成器,實現分批去redis中獲取數據 2 3 # 參數: 4 # match,匹配指定key,默認None 表示所有的key 5 # count,每次分片最少獲取個數,默認None表示采用Redis的默認分片個數 6 7 # 如: 8 # for item in r.hscan_iter(‘xx‘): 9 # print item
3. list
List操作,redis中的List在在內存中按照一個name對應一個List來存儲。如圖:
lpush(name,values)
1 # 在name對應的list中添加元素,每個新的元素都添加到列表的最左邊 2 3 # 如: 4 # r.lpush(‘oo‘, 11,22,33) 5 # 保存順序為: 33,22,11 6 7 # 擴展: 8 # rpush(name, values) 表示從右向左操作
lpushx(name,value)
1 # 在name對應的list中添加元素,只有name已經存在時,值添加到列表的最左邊 2 3 # 更多: 4 # rpushx(name, value) 表示從右向左操作
llen(name)
1 # name對應的list元素的個數
linsert(name, where, refvalue, value))
1 # 在name對應的列表的某一個值前或後插入一個新值 2 3 # 參數: 4 # name,redis的name 5 # where,BEFORE或AFTER 6 # refvalue,標桿值,即:在它前後插入數據 7 # value,要插入的數據
r.lset(name, index, value)
1 # 對name對應的list中的某一個索引位置重新賦值 2 3 # 參數: 4 # name,redis的name 5 # index,list的索引位置 6 # value,要設置的值
r.lrem(name, value, num)
1 # 在name對應的list中刪除指定的值 2 3 # 參數: 4 # name,redis的name 5 # value,要刪除的值 6 # num, num=0,刪除列表中所有的指定值; 7 # num=2,從前到後,刪除2個; 8 # num=-2,從後向前,刪除2個
lpop(name)
1 # 在name對應的列表的左側獲取第一個元素並在列表中移除,返回值則是第一個元素 2 3 # 更多: 4 # rpop(name) 表示從右向左操作
lindex(name, index)
1 在name對應的列表中根據索引獲取列表元素
lrange(name, start, end)
1 # 在name對應的列表分片獲取數據 2 # 參數: 3 # name,redis的name 4 # start,索引的起始位置 5 # end,索引結束位置
ltrim(name, start, end)
1 # 在name對應的列表中移除沒有在start-end索引之間的值 2 # 參數: 3 # name,redis的name 4 # start,索引的起始位置 5 # end,索引結束位置
rpoplpush(src, dst)
1 # 從一個列表取出最右邊的元素,同時將其添加至另一個列表的最左邊 2 # 參數: 3 # src,要取數據的列表的name 4 # dst,要添加數據的列表的name
blpop(keys, timeout)
1 # 將多個列表排列,按照從左到右去pop對應列表的元素 2 3 # 參數: 4 # keys,redis的name的集合 5 # timeout,超時時間,當元素所有列表的元素獲取完之後,阻塞等待列表內有數據的時間(秒), 0 表示永遠阻塞 6 7 # 更多: 8 # r.brpop(keys, timeout),從右向左獲取數據
brpoplpush(src, dst, timeout=0)
1 # 從一個列表的右側移除一個元素並將其添加到另一個列表的左側 2 3 # 參數: 4 # src,取出並要移除元素的列表對應的name 5 # dst,要插入元素的列表對應的name 6 # timeout,當src對應的列表中沒有數據時,阻塞等待其有數據的超時時間(秒),0 表示永遠阻塞
4.set集合操作
Set操作,Set集合就是不允許重復的列表
sadd(name,values)
eg: sadd name 1 2 3 2
1 # name對應的集合中添加元素
scard(name)
eg:scard name
1 獲取name對應的集合中元素個數
sdiff(keys, *args)
eg:sdiff name name1
1 在第一個name對應的集合中且不在其他name對應的集合的元素集合
sdiffstore(dest, keys, *args)
1 # 獲取第一個name對應的集合中且不在其他name對應的集合,再將其新加入到dest對應的集合中
sinter(keys, *args)
1 # 獲取多一個name對應集合的交集
sinterstore(dest, keys, *args)
# 獲取多一個name對應集合的交集,再將其加入到dest對應的集合中
sismember(name, value)
1 # 檢查value是否是name對應的集合的成員
smembers(name)
1 # 獲取name對應的集合的所有成員
smove(src, dst, value)
1 # 將某個成員從一個集合中移動到另外一個集合
spop(name)
1 # 從集合的右側(尾部)移除一個成員,並將其返回
srandmember(name, numbers)
1 # 從name對應的集合中隨機獲取 numbers 個元素
srem(name, values)
1 # 在name對應的集合中刪除某些值
sunion(keys, *args)
1 # 獲取多一個name對應的集合的並集
sunionstore(dest,keys, *args)
1 # 獲取多一個name對應的集合的並集,並將結果保存到dest對應的集合中
sscan(name, cursor=0, match=None, count=None)
sscan_iter(name, match=None, count=None)
1 # 同字符串的操作,用於增量叠代分批獲取元素,避免內存消耗太大
其他常用操作
http://www.cnblogs.com/alex3714/articles/6217453.html
redis緩存數據庫??