日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

day11--RabbitMQ、Redis

發(fā)布時間:2025/4/16 数据库 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 day11--RabbitMQ、Redis 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

??? RabbitMQ:就是消息隊列與Python里面的queue功能類似。線程和進程queue只能Python自己使用;不同機器和程序傳遞消息就要使用RabbitMQ了,中間傳遞。

??? RabbitMQ的功能與Queue的功能一樣,不同的是,線程queue.Queue()用來不同線程之間進行傳遞消息;進程Queue()用來子進程和父進程之間的數(shù)據(jù)交互;或者同屬于同一父進程下多個子進程進行交互。

??? RabbitMQ可以實現(xiàn)多個程序之間的數(shù)據(jù)交互,不需要讓程序去各自維護,統(tǒng)一通過中間商,RabbitMQ實現(xiàn)即可。

??? RabbitMQ地址:(http://erlang.org/download/?S=A/snapshots/otp_src_R14B01.readme/otp_doc_man_R16A_RELEASE_CANDIDATE.tar.gz/otp_win32_R10B-1a.exe/otp_doc_html_R16B.tar.gz/otp_doc_man_R10B-5.tar.gz)

?

??? RabbitMQ是使用erlang開發(fā)的

??? RabbitMQ隊列

??? 安裝?http://www.rabbitmq.com/install-standalone-mac.html

??? 安裝python rabbitMQ module

??? pip install pika

??? easy_install pika

??? https://pypi.python.org/pypi/pika

? ??實現(xiàn)最簡單的隊列通信 ??

??? 由于Linux電腦嘗試了很多次,配置沒有弄好,參考網(wǎng)址:https://www.cnblogs.com/alex3714/articles/5248247.html

??? send端

?

import pikaconnection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() #聲明一個管道#聲明queue channel.queue_declare(queue='hello') #聲明一個"hello"的queue#n RabbitMQ a message can never be sent directly to the queue, it always needs to go through an exchange. channel.basic_publish(exchange='',routing_key='hello',body='Hello World!') #routing_key是queue的名稱 print(" [x] Sent 'Hello World!'") connection.close()

?

??? receive端

import pikaconnection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel()#You may ask why we declare the queue again ? we have already declared it in our previous code. # We could avoid that if we were sure that the queue already exists. For example if send.py program #was run before. But we're not yet sure which program to run first. In such cases it's a good # practice to repeat declaring the queue in both programs. channel.queue_declare(queue='hello')def callback(ch, method, properties, body):print(" [x] Received %r" % body)channel.basic_consume(callback, #如果收到消息,就調(diào)用callback函數(shù)來處理消息queue='hello', #從那個隊列里面接收消息no_ack=True) #不確認(rèn),no_ack=True,服務(wù)器端不確認(rèn);print(' [*] Waiting for messages. To exit press CTRL+C') channel.start_consuming()

????? Work Queues

???

??? 在這種模式下,RabbitMQ會默認(rèn)把p發(fā)的消息依次分發(fā)給各個消費者(c),跟負(fù)載均衡差不多

??? Redis操作(http://www.cnblogs.com/wupeiqi/articles/5132791.html)(http://www.cnblogs.com/alex3714/articles/6217453.html)(https://www.cnblogs.com/alex3714/articles/5248247.html)

??? 正常程序之間可以通過json和pickle傳遞數(shù)據(jù),是通過文件。但是文件之間傳輸效率太低了。因此引入了緩存,緩存是放在內(nèi)存中(硬盤效率太低),因此找一個中間媒介。現(xiàn)在常用的就是redis,下面來了解一下:

? ? redis是一個key-value存儲系統(tǒng)。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數(shù)據(jù)類型都支持push/pop、add/remove及取交并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎(chǔ)上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數(shù)據(jù)都是緩存在內(nèi)存中。區(qū)別是redis會周期性的把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件,并且在次基礎(chǔ)上實現(xiàn)了master-slave(主從)同步。 ?

??? Redis優(yōu)點

??? 1.異常快速?:?Redis是非常快的,每秒可以執(zhí)行大約110000設(shè)置操作,81000個/每秒的讀取操作;

??? 2.支持豐富的數(shù)據(jù)類型?:?Redis支持最大多數(shù)開發(fā)人員已經(jīng)知道如列表,集合,可排序集合,哈希等數(shù)據(jù)類型;這使得在應(yīng)用中很容易解決的各種問題,因為我們知道哪些問題處理使用哪種數(shù)據(jù)類型更好解決;

??? 3.操作都是原子的?:?所有?Redis?的操作都是原子,從而確保當(dāng)兩個客戶同時訪問?Redis?服務(wù)器得到的是更新后的值(最新值);

??? 4.MultiUtility工具:Redis是一個多功能實用工具,可以在很多如:緩存,消息傳遞隊列中使用(Redis原生支持發(fā)布/訂閱),在應(yīng)用程序中,如:Web應(yīng)用程序會話,網(wǎng)站頁面點擊數(shù)等任何短暫的數(shù)據(jù);

? ??安裝Redis環(huán)境

??? 一、Redis安裝和基本使用

1 wget http://download.redis.io/releases/redis-3.0.6.tar.gz 2 tar xzf redis-3.0.6.tar.gz 3 cd redis-3.0.6 4 make

? ??啟動服務(wù)端

src/redis-server

??? 啟動客戶端

1 src/redis-cli 2 redis> set foo bar 3 OK 4 redis> get foo 5 "bar"

??? 二、Python操作Redis

??? Python操作Redis

sudo pip install redis or sudo easy_install redis or 源碼安裝詳見:https://github.com/WoLpH/redis-py

? ?? 緩存里面的數(shù)據(jù)是共享的,是存儲在內(nèi)存中,硬盤的效率太低,redis緩存也是通過socket基礎(chǔ)原理來實現(xiàn)數(shù)據(jù)的共享。redis就是一個類似字典key-value的緩存系統(tǒng)。

??? API使用

??? redis-py 的API的使用可以分類為:

??? 1.連接方式

??? 2.連接池

??? 3.操作

??????? String 操作???????? #簡單的keys-value操作

??????? Hash 操作

??????? List 操作

??????? Set 操作

??????? Sort Set 操作?????? #有序集合

??? 4.管道

??? 5.發(fā)布訂閱

??? 1、操作模式

???? redis-py提供兩個類Redis和StrictRedis用于實現(xiàn)Redis的命令,StrictRedis用于實現(xiàn)大部分官方的命令,并使用官方的語法和命令,Redis是StrictRedis的子類,用于向后兼容舊版本的redis-py。

import redisr = redis.Redis(host='10.211.55.4', port=6379) #連接IP地址和端口號 r.set('foo', 'Bar') print r.get('foo')

  使用redis設(shè)置屬性:

  127.0.0.1:6379> set name alex
  OK
  127.0.0.1:6379> set age 22
  OK

??? set設(shè)置 name名字 alex值

??? keys *查看屬性

??? get來獲取屬性值(get name、get age)實現(xiàn)了兩個程序之間的數(shù)據(jù)共享,QQ、微信都能來取數(shù)據(jù)。??? 如果使用get獲取屬性,屬性不存在,則為空,如下:

? ??127.0.0.1:6379> get name
  "alex"
  127.0.0.1:6379> get foo
  "bar"
  127.0.0.1:6379> get alex
  (nil)
  127.0.0.1:6379> get age
  "22"

??? set使用方式:

??? set name alex ex 2中,ex 2代表設(shè)置存活時間,2代表兩秒,exists存在。set設(shè)置屬性的存活時間。

? ? 2、連接池

? ? redis-py使用connection pool來管理對一個redis server的所有連接,避免每次建立、釋放連接的開銷。默認(rèn),每個Redis實例都會維護一個自己的連接池。可以直接建立一個連接池,然后作為參數(shù)Redis,這樣就可以實現(xiàn)多個Redis實例共享一個連接池。經(jīng)常取數(shù)據(jù),建立socket連接,建立連接池,從池子里面取數(shù)據(jù)。

?

import redis

pool = redis.ConnectionPool(host="127.0.0.1",port=6379) #設(shè)置一個連接池,所有程序都從這個池子里面取數(shù)據(jù)
r = redis.Redis(connection_pool=pool) #建立一個連接實例
r.set("school","oldboy")
print(r.get("school"))
運行結(jié)果如下:
b'oldboy'

?

? ??set(name, value, ex=None, px=None, nx=False, xx=False)

在Redis中設(shè)置值,默認(rèn),不存在則創(chuàng)建,存在則修改 參數(shù):ex,過期時間(秒)px,過期時間(毫秒)nx,如果設(shè)置為True,則只有name不存在時,當(dāng)前set操作才執(zhí)行xx,如果設(shè)置為True,則只有name存在時,崗前set操作才執(zhí)行

??? nx屬性是,如果屬性不存在,才設(shè)置,否則不會設(shè)置,如下:

127.0.0.1:6379[1]> set name alex OK 127.0.0.1:6379[1]> set name Alex nx (nil) 127.0.0.1:6379[1]> get name "alex"

??? 上面,我們設(shè)置了name屬性,接著我們來覆蓋這個屬性,正常如果沒有nx屬性,"alex"將被“Alex"值覆蓋,但是這里設(shè)置了nx,由于name存在,不能覆蓋。nx的作用就是如果屬性存在,則設(shè)置不成功,否則設(shè)置成功。

??? xx只有當(dāng)屬性存在的時候,操作才成功,即只覆蓋原來屬性,原來屬性不存在不會創(chuàng)建新的屬性,如下:

127.0.0.1:6379[1]> get name "alex" 127.0.0.1:6379[1]> set name Alex xx OK 127.0.0.1:6379[1]> get name "Alex" 127.0.0.1:6379[1]> set age 22 xx (nil)

??? 從上面程序可以看出,xx是當(dāng)屬性不存在的時候不會設(shè)置成功,只有當(dāng)屬性存在了,覆蓋原來屬性,是用來覆蓋原來屬性的,屬性存在覆蓋,不存在不會創(chuàng)建。

??? setnx(name, value)

? ??設(shè)置值,只有name不存在時,執(zhí)行設(shè)置操作(添加) ?

??? setex(name, time, value)

# 設(shè)置值 # 參數(shù):# time,過期時間(數(shù)字秒 或 timedelta對象)

??? psetex(key,milliseconds,value)

# 設(shè)置值 # 參數(shù):# time_ms,過期時間(數(shù)字毫秒 或 timedelta對象)

??? mset(*args, **kwargs)

批量設(shè)置值 如:mset(k1='v1', k2='v2')或mget({'k1': 'v1', 'k2': 'v2'})

??? 批量設(shè)置參數(shù),如下:

??? 127.0.0.1:6379[1]> mset k1 v1 k2 v2
  OK
  127.0.0.1:6379[1]> get k1
  "v1"
  127.0.0.1:6379[1]> get k2
  "v2"

??? get(name)

? ? 獲取值

? ??mget(keys, *args) ? ?

批量獲取 如:mget('ylr', 'wupeiqi')或r.mget(['ylr', 'wupeiqi'])

??? mget(keys,*args)是批量獲取值,如下:

??? 127.0.0.1:6379[1]> mget k1 k2
  1) "v1"
  2) "v2"

??? getset(name, value)

??? 設(shè)置新值并獲取原來的值

? ? getset(name,value)是設(shè)置并獲取原來的新值,如果原來的值不存在,則(nil),如果原來的值存在,獲取原來的值,并把新值賦值給原來的屬性。如下:

? ? 127.0.0.1:6379[1]> getset k1 alex ? ? ? ? ? ? ? ? ?? #給k1設(shè)置新值,并獲取k1原來的值
  "v1"??????????????????????????????????????????????????????? #獲取到了k1原來的值
  127.0.0.1:6379[1]> getset k8 tom
  (nil)?????????????????????????????????????????????????????? #屬性k8不存在,則獲取不到原來的值,但是可以設(shè)置k8=tom
  127.0.0.1:6379[1]> get k1
  "alex"????????????????????????????????????????????????????? #屬性k1的值重新設(shè)置了

??? 127.0.0.1:6379[1]> get k8
  "tom"?????????????????????????????????????????????????????? #雖然k8不存在,但是可以設(shè)置

??? getrange(key, start, end)

?

# 獲取子序列(根據(jù)字節(jié)獲取,非字符) # 參數(shù):# name,Redis 的 name# start,起始位置(字節(jié))# end,結(jié)束位置(字節(jié)) # 如: "武沛齊"0-3表示 ""

?

??? 127.0.0.1:6379> getrange school 0 2
  "old"

??? getrange是獲取鍵值的切片長度,字符長度。中文是以字節(jié)形式獲取的,在redis里面,都是以字節(jié)形式存儲的。

? ? 127.0.0.1:6379> getrange myname 0 2
  "\xe8\x80\xbf"

??? setrange(name, offset, value)

?

# 修改字符串內(nèi)容,從指定字符串索引開始向后替換(新值太長時,則向后添加) # 參數(shù):# offset,字符串的索引,字節(jié)(一個漢字三個字節(jié))# value,要設(shè)置的值

?

??? setrange(name,offset,value)從某個設(shè)定的位置開始覆蓋,如下:

??? 127.0.0.1:6379> get school
  "oldboy"
  127.0.0.1:6379> setrange school 2 alex
  (integer) 6
  127.0.0.1:6379> get school
  "olalex"

??? setrange(name,offset,value)向下偏移offset個字符,覆蓋新的值value

??? setbit(name, offset, value)

# 對name對應(yīng)值的二進制表示的位進行操作# 參數(shù):# name,redis的name# offset,位的索引(將值變換成二進制后再進行索引)# value,值只能是 10# 注:如果在Redis中有一個對應(yīng): n1 = "foo",那么字符串foo的二進制表示為:01100110 01101111 01101111所以,如果執(zhí)行 setbit('n1', 7, 1),則就會將第7位設(shè)置為1,那么最終二進制則變成 01100111 01101111 01101111,即:"goo"# 擴展,轉(zhuǎn)換二進制表示:# source = "武沛齊"source = "foo"for i in source:num = ord(i)print bin(num).replace('b','')特別的,如果source是漢字 "武沛齊"怎么辦?答:對于utf-8,每一個漢字占 3 個字節(jié),那么 "武沛齊" 則有 9個字節(jié)對于漢字,for循環(huán)時候會按照 字節(jié) 迭代,那么在迭代時,將每一個字節(jié)轉(zhuǎn)換 十進制數(shù),然后再將十進制數(shù)轉(zhuǎn)換成二進制11100110 10101101 10100110 11100110 10110010 10011011 11101001 10111101 10010000-------------------------- ----------------------------- -----------------------------武 沛 齊

??? bitcount統(tǒng)計列表中1的個數(shù),bitcount,假如要統(tǒng)計一個網(wǎng)站的人數(shù),可以使用數(shù)據(jù)庫來進行統(tǒng)計,可以通過設(shè)置不存在的變量來統(tǒng)計網(wǎng)站在線的人數(shù),比如一個人登錄,就把這個人的ID設(shè)置為1,根據(jù)網(wǎng)站注冊人的ID編號,即是第幾個用戶,然后設(shè)置一個不存在的屬性,如下:

127.0.0.1:6379> setbit n1 1 1 (integer) 0 127.0.0.1:6379> setbit n1 2 1 (integer) 0 127.0.0.1:6379> setbit n1 5 1 (integer) 0 127.0.0.1:6379> bitcount n1 (integer) 3
通過每次用戶登錄之后,把用戶的二進制設(shè)置為1,統(tǒng)計1的個數(shù),就能統(tǒng)計人數(shù)
上面通過設(shè)置,在n1中有三個1存在。

??? setbit(name,offset,value)是按照二進制形式存在的,10101010001001111010011100011100111111100000

??? getbit(name, offset)

? ??# 獲取name對應(yīng)的值的二進制表示中的某位的值 (0或1) ??

? ? 127.0.0.1:6379> getbit n1 1
  (integer) 1
  127.0.0.1:6379> getbit n1 10
  (integer) 0

??? 通過獲取二進制位的值,1代表登錄,0代表未登錄。

??? bitcount(key, start=None, end=None)

# 獲取name對應(yīng)的值的二進制表示中 1 的個數(shù) # 參數(shù):# key,Redis的name# start,位起始位置# end,位結(jié)束位置

??? bitcount(key,start=None,end=None)統(tǒng)計屬性值里面二進制1的個數(shù),比如10100001里面有3個1,bitcount的值就為3.

??? bitop(operation, dest, *keys)

# 獲取多個值,并將值做位運算,將最后的結(jié)果保存至新的name對應(yīng)的值# 參數(shù):# operation,AND(并) 、 OR(或) 、 NOT(非) 、 XOR(異或)# dest, 新的Redis的name# *keys,要查找的Redis的name# 如:bitop("AND", 'new_name', 'n1', 'n2', 'n3')# 獲取Redis中n1,n2,n3對應(yīng)的值,然后講所有的值做位運算(求并集),然后將結(jié)果保存 new_name 對應(yīng)的值中

??? strlen(name)

??? # 返回name對應(yīng)值的字節(jié)長度(一個漢字3個字節(jié))

??? 127.0.0.1:6379> get school
  "olalex\x00\x00\x00\x00tom"
  127.0.0.1:6379> strlen school
  (integer) 13

??? 獲取字節(jié)的長度,strlen(name)是獲取屬性值的字節(jié)長度。

??? incr(self, name, amount=1)

# 自增 name對應(yīng)的值,當(dāng)name不存在時,則創(chuàng)建name=amount,否則,則自增。# 參數(shù):# name,Redis的name# amount,自增數(shù)(必須是整數(shù))# 注:同incrby

?

??? 127.0.0.1:6379> incr n4
  (integer) 1
  127.0.0.1:6379> incr n4
  (integer) 2
  127.0.0.1:6379> incr n4
  (integer) 3

??? 自增屬性,當(dāng)有新值存在是,自動增加1

??? incrbyfloat(self, name, amount=1.0)

?

# 自增 name對應(yīng)的值,當(dāng)name不存在時,則創(chuàng)建name=amount,否則,則自增。# 參數(shù):# name,Redis的name# amount,自增數(shù)(浮點型)

?

??? 可以設(shè)置定值增加,incr是以1每次遞增,incrbyfloat可以以amout=n以任何形式的值自增,如下:

??? 127.0.0.1:6379> incrbyfloat n4 3
  "8"

??? append(key, value)

?

# 在redis name對應(yīng)的值后面追加內(nèi)容# 參數(shù):key, redis的namevalue, 要追加的字符串

?

??? 127.0.0.1:6379> get age
  "22"
  127.0.0.1:6379> append age tom
  (integer) 5
  127.0.0.1:6379> get age
  "22tom"
??? append(key,value)字符串的拼接,屬性拼接值。

??? Hash操作,redis中Hash在內(nèi)存中的存儲格式如下圖:

? ??

??? hash操作其實就是字典的操作,name相當(dāng)于字典名,hash是字典里面的鍵值對,如dict={"k1":"v1","k2":"v2"}就是這樣的鍵值對構(gòu)成,而name屬性就是這個字典的名稱。

??? hset(name, key, value)

# name對應(yīng)的hash中設(shè)置一個鍵值對(不存在,則創(chuàng)建;否則,修改)# 參數(shù):# name,redis的name# key,name對應(yīng)的hash中的key# value,name對應(yīng)的hash中的value# 注:# hsetnx(name, key, value),當(dāng)name對應(yīng)的hash中不存在當(dāng)前key時則創(chuàng)建(相當(dāng)于添加)

??? hset(name,key,value)其中,name就相當(dāng)于字典的名,key鍵,value值,如下:

??? 127.0.0.1:6379> hset info name alex??????????????????? #定義一個字典info,name=alex
  (integer) 1

??? 127.0.0.1:6379> hset info age 38?????????????????????? #添加鍵值對age=38
  (integer) 1

??? hgetall name:獲取name屬性(字典中)所有鍵和值

??? 127.0.0.1:6379> hgetall info
  1) "name"
  2) "alex"
  3) "age"
  4) "38"
  5) "id"
  6) "3344"

??? hget(name,key)

??? #在name對應(yīng)的hash中獲取根據(jù)key獲取value

??? 127.0.0.1:6379> hget info name
  "alex"
  127.0.0.1:6379> hget info age
  "38"

??? hkeys name:查看所有name屬性(字典)中的鍵

??? 127.0.0.1:6379> hkeys info
  1) "name"
  2) "age"
  3) "id"
??? hvals name:獲取所有name屬性(字典)中的值??? 127.0.0.1:6379> hvals info
  1) "alex"
  2) "38"
  3) "3344"

??? hmset(name, mapping)

?

# 在name對應(yīng)的hash中批量設(shè)置鍵值對# 參數(shù):# name,redis的name# mapping,字典,如:{'k1':'v1', 'k2': 'v2'}# 如:# r.hmset('xx', {'k1':'v1', 'k2': 'v2'})

?

??? 127.0.0.1:6379> hmset info2 name wupeiqi age 33 id 3636??????????????? #批量設(shè)置屬性鍵-值
  OK
  127.0.0.1:6379> hkeys info2
  1) "name"
  2) "age"
  3) "id"
??? hmget(name, keys, *args)

# 在name對應(yīng)的hash中獲取多個key的值# 參數(shù):# name,reids對應(yīng)的name# keys,要獲取key集合,如:['k1', 'k2', 'k3']# *args,要獲取的key,如:k1,k2,k3# 如:# r.mget('xx', ['k1', 'k2'])# 或# print r.hmget('xx', 'k1', 'k2')

??? hmget(name,keys,*args)批量獲取值,如下:

??? 127.0.0.1:6379> hmget info2 name age id ? ? ? ?? #同時獲取info2中的name,age,id鍵值
  1) "wupeiqi"
  2) "33"
  3) "3636"

??? hlen(name)
? ? ?# 獲取name對應(yīng)的hash中鍵值對的個數(shù)

?

??? 127.0.0.1:6379> hlen info2??????????????????????? #hlen info2獲取info2中的鍵的個數(shù)
  (integer) 3

??? hexists(name, key)

? ??# 檢查name對應(yīng)的hash是否存在當(dāng)前傳入的key,即判斷name字典中是否包含Key

? ? 127.0.0.1:6379> hexists info2 sex
  (integer) 0
  127.0.0.1:6379> hexists ifno2 name
  (integer) 0
  127.0.0.1:6379> hexists info2 age
  (integer) 1

??? hexists(name,key)判斷name字典中是否存在鍵key,存在返回1;不存在,返回0

??? hdel(name,*keys)
? ??# 將name對應(yīng)的hash中指定key的鍵值對刪除
? ? 127.0.0.1:6379> hvals info2
  1) "wupeiqi"
  2) "33"
  3) "3636"
  4) "female"
  127.0.0.1:6379> hdel info2 sex ? ? ? ? ?? #刪除info2字典中的sex鍵值對
  (integer) 1
  127.0.0.1:6379> hvals info2
  1) "wupeiqi"
  2) "33"
  3) "3636"

??? hincrby(name, key, amount=1)

# 自增name對應(yīng)的hash中的指定key的值,不存在則創(chuàng)建key=amount # 參數(shù):# name,redis中的name# key, hash對應(yīng)的key# amount,自增數(shù)(整數(shù))

?

??? HINCRBY key field increment

? ??127.0.0.1:6379> hincrby info2 age 1
  (integer) 34

??? hincrby info2 age 1意思是:info2字典中age鍵的值增加1,只有整數(shù)才能增加,info2中的name是不可以的,會報錯,ERR hash value is not an integer,提示hash值不是整數(shù)。

??? hincrbyfloat(name, key, amount=1.0)

?

# 自增name對應(yīng)的hash中的指定key的值,不存在則創(chuàng)建key=amount# 參數(shù):# name,redis中的name# key, hash對應(yīng)的key# amount,自增數(shù)(浮點數(shù))# 自增name對應(yīng)的hash中的指定key的值,不存在則創(chuàng)建key=amount

?

??? 自增函數(shù),與上面一樣,只是可以使用浮點數(shù)

??? hscan(name, cursor=0, match=None, count=None)

# 增量式迭代獲取,對于數(shù)據(jù)大的數(shù)據(jù)非常有用,hscan可以實現(xiàn)分片的獲取數(shù)據(jù),并非一次性將數(shù)據(jù)全部獲取完,從而放置內(nèi)存被撐爆# 參數(shù):# name,redis的name# cursor,游標(biāo)(基于游標(biāo)分批取獲取數(shù)據(jù))# match,匹配指定key,默認(rèn)None 表示所有的key# count,每次分片最少獲取個數(shù),默認(rèn)None表示采用Redis的默認(rèn)分片個數(shù)# 如:# 第一次:cursor1, data1 = r.hscan('xx', cursor=0, match=None, count=None)# 第二次:cursor2, data1 = r.hscan('xx', cursor=cursor1, match=None, count=None)# ...# 直到返回值cursor的值為0時,表示數(shù)據(jù)已經(jīng)通過分片獲取完畢

??? hscan(name,cursor=0,match=None,count=None)是用來模糊匹配字典中的屬性。

??? 127.0.0.1:6379> hscan info3 0 match k*????????? #獲取info3中以k開頭的鍵值對
  1) "0"
  2) 1) "k1"
??? 2) "v1"
??? 3) "k2"
??? 4) "v2"
? ? 5) "k3"
? ? 6) "v3"
??? *代表所有,k*代表以*開頭。

??? hscan_iter(name, match=None, count=None)

?

# 利用yield封裝hscan創(chuàng)建生成器,實現(xiàn)分批去redis中獲取數(shù)據(jù)# 參數(shù):# match,匹配指定key,默認(rèn)None 表示所有的key# count,每次分片最少獲取個數(shù),默認(rèn)None表示采用Redis的默認(rèn)分片個數(shù)# 如:# for item in r.hscan_iter('xx'):# print item

?

??? List操作,redis中的List在在內(nèi)存中按照一個name對應(yīng)一個List來存儲。如圖:

??? redis中的列表就是我們常用的列表,只是方式不一樣,定義列表名和列表中的值,等價于name=list()

??? lpush(name,values)

# 在name對應(yīng)的list中添加元素,每個新的元素都添加到列表的最左邊# 如:# r.lpush('oo', 11,22,33)# 保存順序為: 33,22,11# 擴展:# rpush(name, values) 表示從右向左操作

?? lpush(name,values)就是定義一個名字為name的列表,往里面添加值,如下:

??? 127.0.0.1:6379> lpush names alex geng tom wupeiqi??? #定義了一個名字為names的列表,并添加alex,geng,tom,wupeiqi四個值到列表中
  (integer) 4

??? lrange name start end:查看列表中起始值,相當(dāng)于切片,下面查看列表中所有的值:

??? 127.0.0.1:6379> lrange names 0 -1?????????? #查看列表names中所有的值
  1) "wupeiqi"
  2) "tom"
  3) "geng"
  4) "alex"

??? rpush(name,values)

??? # 在name對應(yīng)的list中添加元素,每個新的元素都添加到列表的最右邊

??? 127.0.0.1:6379> rpush names 1 2 3
  (integer) 7

??? 往names列表的右邊添加元素

??? lpushx(name,value)

?

# 在name對應(yīng)的list中添加元素,只有name已經(jīng)存在時,值添加到列表的最左邊# 更多:# rpushx(name, value) 表示從右向左操作

?

??? 127.0.0.1:6379> lpushx ages 22 ? ? ? ?? #列表ages不存在,不能插入值
  (integer) 0

  127.0.0.1:6379> lpushx names cang ? ? ? #列表names存在,可以插入值
  (integer)

??? lpustx(name,value)是向列表中插入值,如果列表存在則插入,如果列表不存在,則不會創(chuàng)建新的列表,不能插入值。

??? llen(name)
??? # name對應(yīng)的list元素的個數(shù)
? ??127.0.0.1:6379> llen names
  (integer) 8 ?

??? llen(name)是查看列表的長度,即列表中有幾個元素。

??? linsert(name, where, refvalue, value)

# 在name對應(yīng)的列表的某一個值前或后插入一個新值# 參數(shù):# name,redis的name# where,BEFORE或AFTER# refvalue,標(biāo)桿值,即:在它前后插入數(shù)據(jù)# value,要插入的數(shù)據(jù)

?

??? linsert(name,where,refvalue,value),LINSERT key BEFORE|AFTER pivot value在某個值前或值后插入一個值,如下:

127.0.0.1:6379> lrange names 0 -1 1) "cang" 2) "wupeiqi" 3) "tom" 4) "geng" 5) "alex" 6) "6666" 7) "1" 8) "2" 9) "3" 127.0.0.1:6379> linsert names before wupeiqi 666 #在wupeiqi前面插入一個666 (integer) 10 127.0.0.1:6379> linsert names after wupeiqi 6666 #在wupeiqi后面插入一個6666值 (integer) 11 127.0.0.1:6379> lrange names 0 -11) "cang"2) "666"3) "wupeiqi"4) "6666"5) "tom"6) "geng"7) "alex"8) "6666"9) "1" 10) "2" 11) "3"

??? linsert()是在指定的值前面或者后面插入一個值。

??? r.lset(name, index, value)

?

# 對name對應(yīng)的list中的某一個索引位置重新賦值# 參數(shù):# name,redis的name# index,list的索引位置# value,要設(shè)置的值

?

??? lset(name,index,value)修改列表中某個索引位置的值,現(xiàn)在我們來修改列表names索引為2位置的值,如下:

127.0.0.1:6379> lrange names 0 3 1) "cang" 2) "666" 3) "wupeiqi" 4) "6666" 127.0.0.1:6379> lset names 2 ALEX #修改列表names中索引為2地方的值為ALEX OK 127.0.0.1:6379> lrange names 0 3 1) "cang" 2) "666" 3) "ALEX" 4) "6666"

? ??r.lrem(name, value, num) ? ? ? ?LREM key count value

?

# 在name對應(yīng)的list中刪除指定的值# 參數(shù):# name,redis的name# value,要刪除的值# num, num=0,刪除列表中所有的指定值;# num=2,從前到后,刪除2個;# num=-2,從后向前,刪除2個

?

??? lrem key count value刪除列表中的值,count是指定刪除幾個,value是刪除的值,key是列表名,如下:

127.0.0.1:6379> lrange names 0 -11) "cang"2) "666"3) "ALEX"4) "6666"5) "tom"6) "geng"7) "alex"8) "6666"9) "1" 10) "2" 11) "3" 127.0.0.1:6379> lrem names 1 1 #刪除列表中的1 (integer) 1 127.0.0.1:6379> lrem names 1 2 #刪除列表中的2 (integer) 1 127.0.0.1:6379> lrange names 0 -1 1) "cang" 2) "666" 3) "ALEX" 4) "6666" 5) "tom" 6) "geng" 7) "alex" 8) "6666" 9) "3"

??? lpop(name)???????????????? LPOP key

# 在name對應(yīng)的列表的左側(cè)獲取第一個元素并在列表中移除,返回值則是第一個元素# 更多:# rpop(name) 表示從右向左操作

?

??? lpop(name)刪除列表中左邊的第一個值,rpop(name)刪除列表中右邊的第一個值,并返回,如下:

127.0.0.1:6379> lpop names #刪除列表names左側(cè)的第一個值,并返回這個值 "cang" 127.0.0.1:6379> rpop names #刪除列表names右側(cè)的第一個值,并返回這個值 "3"

??? lindex(name, index) ? ? ? ? ?LINDEX key index

??? 在name對應(yīng)的列表中根據(jù)索引獲取列表元素,即查詢列表中第index索引處的值

??? 127.0.0.1:6379> lindex names 1?????? #查詢列表names索引為1處的值
??? "ALEX"

??? lrange(name, start, end)

?

# 在name對應(yīng)的列表分片獲取數(shù)據(jù) # 參數(shù):# name,redis的name# start,索引的起始位置# end,索引結(jié)束位置

?

??? ltrim(name, start, end)???????? LTRIM key start stop

?

# 在name對應(yīng)的列表中移除沒有在start-end索引之間的值 # 參數(shù):# name,redis的name# start,索引的起始位置# end,索引結(jié)束位置

?

??? ltrim(name,start,end)移除name列表索引start,end之間以外的所有元素,如下:

??? 127.0.0.1:6379> ltrim names 1 3???????????????? #移除names列表中處索引1-3之外所有的元素,只保留1-3之間的元素
  OK

??? 127.0.0.1:6379> lrange names 0 -1

??? 1) "ALEX"
  2) "6666"
  3) "tom"

??? rpoplpush(src, dst)

?

# 從一個列表取出最右邊的元素,同時將其添加至另一個列表的最左邊 # 參數(shù):# src,要取數(shù)據(jù)的列表的name# dst,要添加數(shù)據(jù)的列表的name

?

??? rpoplpush(src,dst)從一個列表右側(cè)拿出一個值,放入另外一個列表的左側(cè)。

??? blpop(keys, timeout)

?

# 將多個列表排列,按照從左到右去pop對應(yīng)列表的元素# 參數(shù):# keys,redis的name的集合# timeout,超時時間,當(dāng)元素所有列表的元素獲取完之后,阻塞等待列表內(nèi)有數(shù)據(jù)的時間(秒), 0 表示永遠(yuǎn)阻塞# 更多:# r.brpop(keys, timeout),從右向左獲取數(shù)據(jù)

?

??? brpoplpush(src, dst, timeout=0)

?

# 從一個列表的右側(cè)移除一個元素并將其添加到另一個列表的左側(cè)# 參數(shù):# src,取出并要移除元素的列表對應(yīng)的name# dst,要插入元素的列表對應(yīng)的name# timeout,當(dāng)src對應(yīng)的列表中沒有數(shù)據(jù)時,阻塞等待其有數(shù)據(jù)的超時時間(秒),0 表示永遠(yuǎn)阻塞

?

??? Set操作,Set集合就是不允許重復(fù)的列表

? ? sadd(name,values)?
? ??# name對應(yīng)的集合中添加元素 ??

? ??127.0.0.1:6379> sadd nums 1 2 1 3 4??????????????? #創(chuàng)建一個nums集合,并往里面添加值
  (integer) 4 ??

??? smembers(name)

??? #獲取name集合中所有的元素

??? 127.0.0.1:6379> smembers nums?????????? #獲取集合nums中所有的元素
  1) "1"
  2) "2"
  3) "3"
  4) "4"

??? scard(name)
??? 獲取name對應(yīng)的集合中元素個數(shù)
? ??127.0.0.1:6379> scard nums??????????????????????? #獲取集合nums中元素的個數(shù),集合是無序的,無序集合,所以不能使用切片
  (integer) 4 ?? ??

??? sdiff(keys, *args)

??? 在第一個name對應(yīng)的集合中且不在其他name對應(yīng)的集合的元素集合

??? 127.0.0.1:6379> sadd numbers 1 2 3 6 7 9
  (integer) 6
  127.0.0.1:6379> sdiff nums numbers??????????? #獲取nums中有的,numbers中沒有的元素,即對稱差集,nums中有,numbers中沒有的元素
  1) "4"

??? sdiffstore(dest, keys, *args)
??? # 獲取第一個name對應(yīng)的集合中且不在其他name對應(yīng)的集合,再將其新加入到dest對應(yīng)的集合中
??? sinter(keys, *args)
??? #獲取交集

??? 127.0.0.1:6379> sinter numbers nums???????????????? #獲取nums和numbers的交集
  1) "1"
  2) "2"
  3) "3"

??? sinterstore(dest, keys, *args)

??? # 獲取多一個name對應(yīng)集合的交集,再講其加入到dest對應(yīng)的集合中

??? 127.0.0.1:6379> smembers numbers
  1) "1"
  2) "2"
  3) "3"
  4) "6"
  5) "7"
  6) "9"

??? sismember(name, value)

??? # 檢查value是否是name對應(yīng)的集合的成員

? ??smove(src, dst, value) ??
? ?? #將某個成員從一個集合中移動到另外一個集合 ??
??? spop(name)

??? # 從集合的右側(cè)(尾部)移除一個成員,并將其返回

??? srandmember(name, numbers)

? ??# 從name對應(yīng)的集合中隨機獲取 numbers 個元素

? ??127.0.0.1:6379> srandmember nums 2????????? #從集合num2中隨機獲取兩個元素
? ? 1) "1"
? ? 2) "6" ?

??? srem(name, values)

??? # 在name對應(yīng)的集合中刪除某些值
? ? 127.0.0.1:6379> srem nums 6??????? #刪除集合中指定的值
  (integer) 1

? ??sunion(keys, *args) ??
??? # 獲取多一個name對應(yīng)的集合的并集
? ??sunionstore(dest,keys, *args) ?

? ?# 獲取多一個name對應(yīng)的集合的并集,并將結(jié)果保存到dest對應(yīng)的集合中? ???

???? sscan(name, cursor=0, match=None, count=None)

??? sscan_iter(name, match=None, count=None)

??? # 同字符串的操作,用于增量迭代分批獲取元素,避免內(nèi)存消耗太大

? ??有序集合,在集合的基礎(chǔ)上,為每元素排序;元素的排序需要根據(jù)另外一個值來進行比較,所以,對于有序集合,每一個元素有兩個值,即:值和分?jǐn)?shù),分?jǐn)?shù)專門用來做排序。 ??

??? zadd(name, *args, **kwargs) ? ? ? ?ZADD key [NX|XX] [CH] [INCR] score member [score member ...]? ? ?

# 在name對應(yīng)的有序集合中添加元素 # 如:# zadd('zz', 'n1', 1, 'n2', 2)# 或# zadd('zz', n1=11, n2=22)

??? 127.0.0.1:6379> zadd people 1 alex 2 wupeiqi??????????? #創(chuàng)建有序集合,有序集合名people,分?jǐn)?shù)1,名字alex;分?jǐn)?shù)2,名字wupeiqi
  (integer) 2

??? zrange(name,start,end) ? ? ? ? ? ? ?

??? #根據(jù)分?jǐn)?shù)高低進行排序

??? 127.0.0.1:6379> zrange people 0 -1 ? ? ? ? ? ? ? ?? #獲取有序集合中的索引元素
  1) "alex"
  2) "wupeiqi"

??? 在有序集合中,分?jǐn)?shù)可以更改,但是值只有一個。

??? 可以顯示分?jǐn)?shù)zrange name start end wihtscores

??? 127.0.0.1:6379> zrange people 0 -1 withscores?????????????????????? #顯示people有序集合的元素,并顯示分?jǐn)?shù)
  1) "alex"
  2) "1"
  3) "wupeiqi"
  4) "2"

??? zcard(name)

??? # 獲取name對應(yīng)的有序集合元素的數(shù)量

? ??127.0.0.1:6379> zcard people????? #獲取有序集合中的元素數(shù)量
  (integer) 2 ??

??? zcount(name, min, max)

??? # 獲取name對應(yīng)的有序集合中分?jǐn)?shù) 在 [min,max] 之間的個數(shù)

??? 127.0.0.1:6379> zcount people 1 9 ? ? ? ? ? #統(tǒng)計people集合中分?jǐn)?shù)在1-9之間元素的個數(shù)
  (integer) 4

??? zincrby(name, value, amount)

??? # 自增name對應(yīng)的有序集合的 name 對應(yīng)的分?jǐn)?shù)

??? r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)

# 按照索引范圍獲取name對應(yīng)的有序集合的元素# 參數(shù):# name,redis的name# start,有序集合索引起始位置(非分?jǐn)?shù))# end,有序集合索引結(jié)束位置(非分?jǐn)?shù))# desc,排序規(guī)則,默認(rèn)按照分?jǐn)?shù)從小到大排序# withscores,是否獲取元素的分?jǐn)?shù),默認(rèn)只獲取元素的值# score_cast_func,對分?jǐn)?shù)進行數(shù)據(jù)轉(zhuǎn)換的函數(shù)# 更多:# 從大到小排序# zrevrange(name, start, end, withscores=False, score_cast_func=float)# 按照分?jǐn)?shù)范圍獲取name對應(yīng)的有序集合的元素# zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)# 從大到小排序# zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)

??? zrank(name, value)

獲取某個值在 name對應(yīng)的有序集合中的排行(從 0 開始)# 更多:# zrevrank(name, value),從大到小排序

??? zrangebylex(name, min, max, start=None, num=None)

# 當(dāng)有序集合的所有成員都具有相同的分值時,有序集合的元素會根據(jù)成員的 值 (lexicographical ordering)來進行排序,而這個命令則可以返回給定的有序集合鍵 key 中, 元素的值介于 min 和 max 之間的成員 # 對集合中的每個成員進行逐個字節(jié)的對比(byte-by-byte compare), 并按照從低到高的順序, 返回排序后的集合成員。 如果兩個字符串有一部分內(nèi)容是相同的話, 那么命令會認(rèn)為較長的字符串比較短的字符串要大# 參數(shù):# name,redis的name# min,左區(qū)間(值)。 + 表示正無限; - 表示負(fù)無限; ( 表示開區(qū)間; [ 則表示閉區(qū)間# min,右區(qū)間(值)# start,對結(jié)果進行分片處理,索引位置# num,對結(jié)果進行分片處理,索引后面的num個元素# 如:# ZADD myzset 0 aa 0 ba 0 ca 0 da 0 ea 0 fa 0 ga# r.zrangebylex('myzset', "-", "[ca") 結(jié)果為:['aa', 'ba', 'ca']# 更多:# 從大到小排序# zrevrangebylex(name, max, min, start=None, num=None)

??? zrem(name, values)

# 刪除name對應(yīng)的有序集合中值是values的成員# 如:zrem('zz', ['s1', 's2'])

??? zremrangebyrank(name, min, max)

??? #根據(jù)排行范圍刪除

? ? zremrangebyscore(name,min,max) ??

??? #根據(jù)分?jǐn)?shù)范圍刪除

??? zremrangebylex(name,min,max)

??? #根據(jù)值返回刪除??? zscore(name, value)

??? #獲取name對應(yīng)有序集合中value對應(yīng)的分?jǐn)?shù)? ??? zinterstore(dest, keys, aggregate=None)

# 獲取兩個有序集合的交集,如果遇到相同值不同分?jǐn)?shù),則按照aggregate進行操作 # aggregate的值為: SUM MIN MAX

??? zunionstore(dest, keys, aggregate=None)

# 獲取兩個有序集合的并集,如果遇到相同值不同分?jǐn)?shù),則按照aggregate進行操作 # aggregate的值為: SUM MIN MAX

??? zscan(name, cursor=0, match=None, count=None, score_cast_func=float)

??? zscan_iter(name, match=None, count=None,score_cast_func=float)

??? # 同字符串相似,相較于字符串新增score_cast_func,用來對分?jǐn)?shù)進行操作

??? 其他常用操作:

??? delete(*names)???? ---del name

# 根據(jù)刪除redis中的任意數(shù)據(jù)類型

??? del name刪除redis中名字是name的集合,元素的名稱,如下:

127.0.0.1:6379> del n4 #刪除redis中名稱為n4的元素(字符串名稱,列表名,字典名,集合名,有序集合名) (integer) 1 127.0.0.1:6379> keys *1) "numbers"2) "names"3) "info2"4) "number"5) "myname"6) "foo"7) "nums"8) "info3"9) "age" 10) "info" 11) "n1" 12) "school" 13) "ifno2"

??? exists(name)

# 檢測redis的name是否存在

??? 127.0.0.1:6379> exists myname?? #檢測redis中是否存在名稱為myname的命名
  (integer) 1
  127.0.0.1:6379> exists tom
  (integer) 0

??? keys(pattern="*")

# 根據(jù)模型獲取redis的name# 更多:# KEYS * 匹配數(shù)據(jù)庫中所有 key 。# KEYS h?llo 匹配 hello , hallo 和 hxllo 等。# KEYS h*llo 匹配 hllo 和 heeeeello 等。# KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo

??? keys(parrern="*")里面可以加正則表達式,默認(rèn)是匹配所有,也可以加正則進行匹配

??? 127.0.0.1:6379> keys n*?????????????????? #匹配以n開頭的所有命名
  1) "numbers"
  2) "names"
  3) "number"
  4) "nums"
  5) "n1"

? ? expire(name,time) ?

# 為某個redis的某個name設(shè)置超時時間

??? rename(src,dst)

# 對redis的name重命名為

??? 修改名字,如下:

??? 127.0.0.1:6379> rename ifno2 info??????? #修改ifno2的名字為info
  OK
  127.0.0.1:6379> keys *
  1) "numbers"
  2) "names"
  3) "number"
  4) "nums"
  5) "age"
  6) "info"
  7) "school"

??? move(name,db) ?? #redis默認(rèn)有15個db

# 將redis的某個值移動到指定的db下

??? randomkey()

# 隨機獲取一個redis的name(不刪除)

??? 127.0.0.1:6379> randomkey????????? #隨機獲取一個key
  "info"
  127.0.0.1:6379> randomkey
  "name

??? type(name)??

# 獲取name對應(yīng)值的類型

??? type(name)是查看變量的類型,是字典,集合、字符串等等;如下:

127.0.0.1:6379> type numbers #查看numbers的類型,集合 set 127.0.0.1:6379> type names #查看names的類型,列表 list 127.0.0.1:6379> type info #查看info的類型,hash哈希(即字典) hash 127.0.0.1:6379> type school #查看school的類型,字符串 string
127.0.0.1:6379> type vip #查看vip的類型,有序集合
zset

??? scan(cursor=0,match=None,count=None)

??? scan_iter(match=None,count=None)

??? #同字符串操作,用戶增量迭代獲取key

??? 4、管道

? ??redis-py默認(rèn)在執(zhí)行每次請求都會創(chuàng)建(連接池申請連接)和斷開(歸還連接池)一次連接操作,如果想要在一次請求中指定多個命令,則可以使用pipline實現(xiàn)一次請求指定多個命令,并且默認(rèn)情況下一次pipline 是原子性操作.

? ??5、發(fā)布訂閱 ?

? ??

??? 發(fā)布者:服務(wù)器

??? 訂閱者:Dashboad和數(shù)據(jù)處理(http://www.cnblogs.com/wupeiqi/articles/5132791.html)

??? Demo如下:

import redisclass RedisHelper:def __init__(self):self.__conn = redis.Redis(host='10.211.55.4')self.chan_sub = 'fm104.5'self.chan_pub = 'fm104.5'def public(self, msg):self.__conn.publish(self.chan_pub, msg)return Truedef subscribe(self):pub = self.__conn.pubsub()pub.subscribe(self.chan_sub)pub.parse_response()return pub

??? 訂閱者:

from monitor.RedisHelper import RedisHelperobj = RedisHelper() redis_sub = obj.subscribe()while True:msg= redis_sub.parse_response()print msg

??? 發(fā)布者:

from monitor.RedisHelper import RedisHelperobj = RedisHelper() obj.public('hello')

轉(zhuǎn)載于:https://www.cnblogs.com/gengcx/p/7512807.html

總結(jié)

以上是生活随笔為你收集整理的day11--RabbitMQ、Redis的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。