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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

数据库

Redis:安装、配置、操作和简单代码实例(C语言Client端)[转]

發(fā)布時(shí)間:2024/6/18 数据库 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis:安装、配置、操作和简单代码实例(C语言Client端)[转] 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

我轉(zhuǎn)的地址:?http://blog.csdn.net/hj19870806/article/details/8724907

聽(tīng)說(shuō)游戲的用的比較多,所以了解下。

--以下為轉(zhuǎn)載內(nèi)容

Redis是一個(gè)開(kāi)源的使用ANSI C語(yǔ)言編寫(xiě)、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫(kù),并提供多種語(yǔ)言的API。從2010年3月15日起,Redis的開(kāi)發(fā)工作由VMware主持。

  如何安裝Redis?

  Redis的官方下載站是http://redis.io/download,可以去上面下載最新的安裝程序下來(lái),我寫(xiě)此文章時(shí)的的穩(wěn)定版本是2.2.12。

  怎么安裝 Redis數(shù)據(jù)庫(kù)呢?下面將介紹Linux版本的安裝方法:

  步驟一: 下載Redis

  下載安裝包:wget http://redis.googlecode.com/files/redis-2.2.12.tar.gz

[root@localhost 4setup]# wget http://redis.googlecode.com/files/redis-2.2.12.tar.gz

  --19:06:56--?http://redis.googlecode.com/files/redis-2.2.12.tar.gz

  正在解析主機(jī) redis.googlecode.com...?74.125.71.82

  Connecting to redis.googlecode.com|74.125.71.82|:80... 已連接。

  已發(fā)出 HTTP 請(qǐng)求,正在等待回應(yīng)...?200?OK

  長(zhǎng)度:455240?(445K) [application/x-gzip]

  Saving to: `redis-2.2.12.tar.gz'

  100%[==========================================>]455,24034.8K/sin?13s

  19:07:16?(34.8?KB/s)?-?`redis-2.2.12.tar.gz'?saved [455240/455240]

  [root@localhost 4setup]#

  步驟二: 編譯源程序

[root@localhost 4setup]# ll

  總計(jì)?29168

  -rw-r--r--1?root root?4552402011-07-22?redis-2.2.12.tar.gz

  [root@localhost 4setup]# tar xzf redis-2.2.12.tar.gz

  [root@localhost 4setup]# cd redis-2.2.12

  [root@localhost redis-2.2.12]# make

  cd src?&&?make all

  make[1]: Entering directory `/root/4setup/redis-2.2.12/src'

  步驟三: 啟動(dòng)Redis服務(wù)

src/redis-server

  [root@localhost redis-2.2.12]# src/redis-server

  [6246]?05?Aug?19:17:22?# Warning: no config file specified, using the default config. In order?to?specify a config file use'redis-server /path/to/redis.conf'

  [6246]?05?Aug?19:17:22*?Server started, Redis version?2.2.12

  [6246]?05?Aug?19:17:22?# WARNING overcommit_memory?issetto0! Background save may fail under low memory condition.Tofix?this issue add'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

  [6246]?05?Aug?19:17:22*?The server?isnow?readyto?accept connectionson?port?6379

  [6246]?05?Aug?19:17:22-0?clients connected (0?slaves),539544?bytes in use

  Redis 服務(wù)端的默認(rèn)連接端口是 6379。

  步驟四: 將Redis作為 Linux 服務(wù)隨機(jī)啟動(dòng)

  vi /etc/rc.local, 使用vi編輯器打開(kāi)隨機(jī)啟動(dòng)配置文件,并在其中加入下面一行代碼。

/root/4setup/redis-2.2.12/src/redis-server

  步驟五: 客戶端連接驗(yàn)證

  新打開(kāi)一個(gè)Session輸入:src/redis-cli,如果出現(xiàn)下面提示,那么您就可以開(kāi)始Redis之旅了。

[root@localhost redis-2.2.12]# src/redis-cli

  redis?127.0.0.1:6379>

  步驟六: 查看Redis日志

  查看服務(wù)器端session,即可對(duì)Redis的運(yùn)行狀況進(jìn)行查看或分析了。

[6246]05?Aug19:24:33-0?clients connected (0?slaves),539544?bytes in use

  [6246]?05?Aug?19:24:37-?Accepted?127.0.0.1:51381

  [6246]?05?Aug?19:24:38-1?clients connected (0?slaves),547372?bytes in use

  以上的幾個(gè)步驟就OK了!!這樣一個(gè)簡(jiǎn)單的Redis數(shù)據(jù)庫(kù)就可以暢通無(wú)阻地運(yùn)行起來(lái)了。

  步驟七: 停止Redis實(shí)例

  最簡(jiǎn)單的方法是在啟動(dòng)實(shí)例的session中,直接使用Control-C來(lái)將實(shí)例停止。

  我們還可以用客戶端來(lái)停止服務(wù),如可以用shutdown來(lái)停止Redis實(shí)例, 具體如下:

[root@localhost redis-2.2.12]# src/redis-cli shutdown

?

  如何配置Redis?

  如果是一個(gè)專業(yè)的DBA,那么實(shí)例啟動(dòng)時(shí)會(huì)加很多的參數(shù)以便使系統(tǒng)運(yùn)行的非常穩(wěn)定,這樣就可能會(huì)在啟動(dòng)時(shí)在Redis后面加一個(gè)參數(shù),以指定配置文件的路徑,就象mysql一樣的讀取啟動(dòng)配置文件的方式來(lái)啟動(dòng)數(shù)據(jù)庫(kù)。源碼編譯完成后,在redis-2.2.12目錄下有一個(gè)redis.conf文件,這個(gè)文件即是Redis的配置文件,用配置文件來(lái)啟動(dòng)Redis的方法如下:

[root@localhost redis-2.2.12]# src/redis-server redis.conf

  [6353]?05?Aug?19:36:45*?Server started, Redis version?2.2.12

  [6353]?05?Aug?19:36:45?# WARNING overcommit_memory?issetto0! Background save may fail under low memory condition.Tofix?this issue add'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

  [6353]?05?Aug?19:36:45*?The server?isnow?readyto?accept connectionson?port?6379

  [6353]?05?Aug?19:36:45-0?clients connected (0?slaves),539540?bytes in use

  Redis支持很多的參數(shù),但都有默認(rèn)值。

  ●daemonize:

  默認(rèn)情況下,redis不是在后臺(tái)運(yùn)行的,如果需要在后臺(tái)運(yùn)行,把該項(xiàng)的值更改為yes。

  ●pidfile

  當(dāng)Redis在后臺(tái)運(yùn)行的時(shí)候,Redis默認(rèn)會(huì)把pid文件放在/var/run/redis.pid,你可以配置到其他地址。當(dāng)運(yùn)行多個(gè)redis服務(wù)時(shí),需要指定不同的pid文件和端口。

  ●bind

  指定Redis只接收來(lái)自于該IP地址的請(qǐng)求,如果不進(jìn)行設(shè)置,那么將處理所有請(qǐng)求,在生產(chǎn)環(huán)境中最好設(shè)置該項(xiàng)。

  ●port

  監(jiān)聽(tīng)端口,默認(rèn)為6379。

  ●timeout

  設(shè)置客戶端連接時(shí)的超時(shí)時(shí)間,單位為秒。當(dāng)客戶端在這段時(shí)間內(nèi)沒(méi)有發(fā)出任何指令,那么關(guān)閉該連接。

  ●loglevel

  log等級(jí)分為4級(jí),debug, verbose, notice, 和warning。生產(chǎn)環(huán)境下一般開(kāi)啟notice。

  ●logfile

  配置log文件地址,默認(rèn)使用標(biāo)準(zhǔn)輸出,即打印在命令行終端的窗口上。

  ●databases

  設(shè)置數(shù)據(jù)庫(kù)的個(gè)數(shù),可以使用SELECT 命令來(lái)切換數(shù)據(jù)庫(kù)。默認(rèn)使用的數(shù)據(jù)庫(kù)是0。

  ●save

  設(shè)置Redis進(jìn)行數(shù)據(jù)庫(kù)鏡像的頻率。

  if(在60秒之內(nèi)有10000個(gè)keys發(fā)生變化時(shí)){

  進(jìn)行鏡像備份

  }else if(在300秒之內(nèi)有10個(gè)keys發(fā)生了變化){

  進(jìn)行鏡像備份

  }else if(在900秒之內(nèi)有1個(gè)keys發(fā)生了變化){

  進(jìn)行鏡像備份

  }

?

  ●rdbcompression

  在進(jìn)行鏡像備份時(shí),是否進(jìn)行壓縮。

  ●dbfilename

  鏡像備份文件的文件名。

  ●dir

  數(shù)據(jù)庫(kù)鏡像備份的文件放置的路徑。這里的路徑跟文件名要分開(kāi)配置是因?yàn)镽edis在進(jìn)行備份時(shí),先會(huì)將當(dāng)前數(shù)據(jù)庫(kù)的狀態(tài)寫(xiě)入到一個(gè)臨時(shí)文件中,等備份完成時(shí),再把該該臨時(shí)文件替換為上面所指定的文件,而這里的臨時(shí)文件和上面所配置的備份文件都會(huì)放在這個(gè)指定的路徑當(dāng)中。

  ●slaveof

  設(shè)置該數(shù)據(jù)庫(kù)為其他數(shù)據(jù)庫(kù)的從數(shù)據(jù)庫(kù)。

  ●masterauth

  當(dāng)主數(shù)據(jù)庫(kù)連接需要密碼驗(yàn)證時(shí),在這里指定。

  ●requirepass

  設(shè)置客戶端連接后進(jìn)行任何其他指定前需要使用的密碼。警告:因?yàn)閞edis速度相當(dāng)快,所以在一臺(tái)比較好的服務(wù)器下,一個(gè)外部的用戶可以在一秒鐘進(jìn)行150K次的密碼嘗試,這意味著你需要指定非常非常強(qiáng)大的密碼來(lái)防止暴力破解。

  ●maxclients

  限制同時(shí)連接的客戶數(shù)量。當(dāng)連接數(shù)超過(guò)這個(gè)值時(shí),redis將不再接收其他連接請(qǐng)求,客戶端嘗試連接時(shí)將收到error信息。

  ●maxmemory

  設(shè)置redis能夠使用的最大內(nèi)存。當(dāng)內(nèi)存滿了的時(shí)候,如果還接收到set命令,redis將先嘗試剔除設(shè)置過(guò)expire信息的key,而不管該key的過(guò)期時(shí)間還沒(méi)有到達(dá)。在刪除時(shí),將按照過(guò)期時(shí)間進(jìn)行刪除,最早將要被過(guò)期的key將最先被刪除。如果帶有expire信息的key都刪光了,那么將返回錯(cuò)誤。這樣,redis將不再接收寫(xiě)請(qǐng)求,只接收get請(qǐng)求。maxmemory的設(shè)置比較適合于把redis當(dāng)作于類似memcached的緩存來(lái)使用。

  ●appendonly

  默認(rèn)情況下,redis會(huì)在后臺(tái)異步的把數(shù)據(jù)庫(kù)鏡像備份到磁盤(pán),但是該備份是非常耗時(shí)的,而且備份也不能很頻繁,如果發(fā)生諸如拉閘限電、拔插頭等狀況,那么將造成比較大范圍的數(shù)據(jù)丟失。所以redis提供了另外一種更加高效的數(shù)據(jù)庫(kù)備份及災(zāi)難恢復(fù)方式。開(kāi)啟append only模式之后,redis會(huì)把所接收到的每一次寫(xiě)操作請(qǐng)求都追加到appendonly.aof文件中,當(dāng)redis重新啟動(dòng)時(shí),會(huì)從該文件恢復(fù)出之前的狀態(tài)。但是這樣會(huì)造成appendonly.aof文件過(guò)大,所以redis還支持了BGREWRITEAOF指令,對(duì)appendonly.aof進(jìn)行重新整理。所以我認(rèn)為推薦生產(chǎn)環(huán)境下的做法為關(guān)閉鏡像,開(kāi)啟appendonly.aof,同時(shí)可以選擇在訪問(wèn)較少的時(shí)間每天對(duì)appendonly.aof進(jìn)行重寫(xiě)一次。

  ●appendfsync

  設(shè)置對(duì)appendonly.aof文件進(jìn)行同步的頻率。always表示每次有寫(xiě)操作都進(jìn)行同步,everysec表示對(duì)寫(xiě)操作進(jìn)行累積,每秒同步一次。這個(gè)需要根據(jù)實(shí)際業(yè)務(wù)場(chǎng)景進(jìn)行配置。

  ●vm-enabled

  是否開(kāi)啟虛擬內(nèi)存支持。因?yàn)閞edis是一個(gè)內(nèi)存數(shù)據(jù)庫(kù),而且當(dāng)內(nèi)存滿的時(shí)候,無(wú)法接收新的寫(xiě)請(qǐng)求,所以在redis 2.0中,提供了虛擬內(nèi)存的支持。但是需要注意的是,redis中,所有的key都會(huì)放在內(nèi)存中,在內(nèi)存不夠時(shí),只會(huì)把value值放入交換區(qū)。這樣保證了雖然使用虛擬內(nèi)存,但性能基本不受影響,同時(shí),你需要注意的是你要把vm-max-memory設(shè)置到足夠來(lái)放下你的所有的key。

  ●vm-swap-file

  設(shè)置虛擬內(nèi)存的交換文件路徑。

  ●vm-max-memory

  這里設(shè)置開(kāi)啟虛擬內(nèi)存之后,redis將使用的最大物理內(nèi)存的大小。默認(rèn)為0,redis將把他所有的能放到交換文件的都放到交換文件中,以盡量少的使用物理內(nèi)存。在生產(chǎn)環(huán)境下,需要根據(jù)實(shí)際情況設(shè)置該值,最好不要使用默認(rèn)的0。

  ●vm-page-size

  設(shè)置虛擬內(nèi)存的頁(yè)大小,如果你的value值比較大,比如說(shuō)你要在value中放置博客、新聞之類的所有文章內(nèi)容,就設(shè)大一點(diǎn),如果要放置的都是很小的內(nèi)容,那就設(shè)小一點(diǎn)。

  ●vm-pages

  設(shè)置交換文件的總的page數(shù)量,需要注意的是,page table信息會(huì)放在物理內(nèi)存中,每8個(gè)page就會(huì)占據(jù)RAM中的1個(gè)byte。總的虛擬內(nèi)存大小 = vm-page-size * vm-pages。

  ●vm-max-threads

  設(shè)置VM IO同時(shí)使用的線程數(shù)量。因?yàn)樵谶M(jìn)行內(nèi)存交換時(shí),對(duì)數(shù)據(jù)有編碼和解碼的過(guò)程,所以盡管IO設(shè)備在硬件上本上不能支持很多的并發(fā)讀寫(xiě),但是還是如果你所保存的vlaue值比較大,將該值設(shè)大一些,還是能夠提升性能的。

  ●glueoutputbuf

  把小的輸出緩存放在一起,以便能夠在一個(gè)TCP packet中為客戶端發(fā)送多個(gè)響應(yīng),具體原理和真實(shí)效果我不是很清楚。所以根據(jù)注釋,你不是很確定的時(shí)候就設(shè)置成yes。

  ●hash-max-zipmap-entries

  在redis 2.0中引入了hash數(shù)據(jù)結(jié)構(gòu)。當(dāng)hash中包含超過(guò)指定元素個(gè)數(shù)并且最大的元素沒(méi)有超過(guò)臨界時(shí),hash將以一種特殊的編碼方式(大大減少內(nèi)存使用)來(lái)存儲(chǔ),這里可以設(shè)置這兩個(gè)臨界值。

  ●activerehashing

  開(kāi)啟之后,redis將在每100毫秒時(shí)使用1毫秒的CPU時(shí)間來(lái)對(duì)redis的hash表進(jìn)行重新hash,可以降低內(nèi)存的使用。當(dāng)你的使用場(chǎng)景中,有非常嚴(yán)格的實(shí)時(shí)性需要,不能夠接受Redis時(shí)不時(shí)的對(duì)請(qǐng)求有2毫秒的延遲的話,把這項(xiàng)配置為no。如果沒(méi)有這么嚴(yán)格的實(shí)時(shí)性要求,可以設(shè)置為yes,以便能夠盡可能快的釋放內(nèi)存。

?

  操作Redis數(shù)據(jù)庫(kù)

  下面我們來(lái)簡(jiǎn)單的操作一下數(shù)據(jù)庫(kù)。

  1、插入數(shù)據(jù)

redis?127.0.0.1:6379>set?name wwl

  OK

  設(shè)置一個(gè)key-value對(duì)。

  2、查詢數(shù)據(jù)

redis?127.0.0.1:6379>get?name

  "wwl"

  取出key所對(duì)應(yīng)的value。

  3、刪除鍵值

redis?127.0.0.1:6379>?del name

  刪除這個(gè)key及對(duì)應(yīng)的value。

  4、驗(yàn)證鍵是否存在

redis?127.0.0.1:6379>exists?name

  (integer)0

  其中0,代表此key不存在;1代表存在。??

redis客戶端(C語(yǔ)言)

上面介紹了redis 安裝和簡(jiǎn)單使用操作,下面,我們來(lái)介紹一下redis client端的編寫(xiě)。

?

[root@localhost redis-2.2.12]# cd deps/hiredis/
[root@localhost hiredis]# make?
cc -c -std=c99 -pedantic -O3 -fPIC -Wall -W -Wwrite-strings??? -g -ggdb? net.c
cc -c -std=c99 -pedantic -O3 -fPIC -Wall -W -Wwrite-strings??? -g -ggdb? hiredis.c
cc -c -std=c99 -pedantic -O3 -fPIC -Wall -W -Wwrite-strings??? -g -ggdb? sds.c
cc -c -std=c99 -pedantic -O3 -fPIC -Wall -W -Wwrite-strings??? -g -ggdb? async.c
gcc -shared -Wl,-soname,libhiredis.so -o libhiredis.so net.o hiredis.o sds.o async.o
cc -c -std=c99 -pedantic -O3 -fPIC -Wall -W -Wwrite-strings??? -g -ggdb? example.c
cc -o hiredis-example -std=c99 -pedantic -O3 -fPIC -Wall -W -Wwrite-strings?? -lm -pthread -g -ggdb -L. -Wl,-rpath,. -lhiredis example.o
cc -c -std=c99 -pedantic -O3 -fPIC -Wall -W -Wwrite-strings??? -g -ggdb? test.c
cc -o hiredis-test -std=c99 -pedantic -O3 -fPIC -Wall -W -Wwrite-strings?? -lm -pthread -g -ggdb -L. -Wl,-rpath,. -lhiredis test.o
[root@localhost hiredis]# make install?
?ar rcs libhiredis.a net.o hiredis.o sds.o async.o
mkdir -p /usr/local/include/hiredis /usr/local/lib
cp -a hiredis.h async.h adapters /usr/local/include/hiredis
cp -a libhiredis.so libhiredis.a /usr/local/lib

這種方式安裝的安裝庫(kù),沒(méi)有到達(dá)默認(rèn)目錄,需要我們:
[root@localhost hiredis] cp libhiredis.so /usr/lib64 /usr/lib? (若是32系統(tǒng)只需要運(yùn)行 cp libhiredis.so /usr/lib)
[root@localhost hiredis]# gcc test.c -o test -lhiredis
[root@loaclhost hiredis]# ./test?
#01 Format command without interpolation: PASSED
#02 Format command with %s string interpolation: PASSED
#03 Format command with %s and an empty string: PASSED
#04 Format command with %b string interpolation: PASSED
#05 Format command with %b and an empty string: PASSED
#06 Format command with literal %: PASSED
#07 Format command with printf-delegation (long long): PASSED
#08 Format command with printf-delegation (float): PASSED
#09 Format command with printf-delegation and extra interpolation: PASSED
#10 Format command with wrong printf format and extra interpolation: PASSED
#11 Format command by passing argc/argv without lengths: PASSED
#12 Format command by passing argc/argv with lengths: PASSED
#13 Returns error when host cannot be resolved: FAILED
#14 Returns error when the port is not open: PASSED
#15 Is able to deliver commands: PASSED
#16 Is a able to send commands verbatim: PASSED
#17 %s String interpolation works: PASSED
#18 %b String interpolation works: PASSED
#19 Binary reply length is correct: PASSED
#20 Can parse nil replies: PASSED
#21 Can parse integer replies: PASSED
#22 Can parse multi bulk replies: PASSED
#23 Can handle nested multi bulk replies: PASSED
#24 Returns I/O error when the connection is lost: PASSED
#25 Error handling in reply parser: PASSED
#26 Memory cleanup in reply parser: PASSED
#27 Set error on nested multi bulks with depth > 1: FAILED
#28 Works with NULL functions for reply: PASSED
#29 Works when a single newline (\r\n) covers two calls to feed: PASSED
#30 Throughput:
??? (1000x PING: 0.04s)
??? (1000x LRANGE with 500 elements: 0.16s)
*** 2 TESTS FAILED ***

不需要關(guān)注上面的兩個(gè)FAILED,當(dāng)然你也可以查資料修補(bǔ)。
[root@localhost hiredis]# gcc example.c? -o example -lhiredis
[root@localhost hiredis]# ./example?
PING: PONG
SET: OK
SET (binary API): OK
GET foo: hello world
INCR counter: 3
INCR counter: 4
0) element-9
1) element-8
2) element-7
3) element-6
4) element-5
5) element-4
6) element-3
7) element-2
8) element-1
9) element-0

編程時(shí),可以參照example.c 的實(shí)例即可

自己編寫(xiě)的程序

? 在下面的代碼示例中,將給出兩種最為常用的Redis命令操作方式,既普通調(diào)用方式和基于管線的調(diào)用方式。

?

[cpp]?view plaincopy
  • #include?<stdio.h>??
  • ?#include?<stdlib.h>??
  • ?#include?<stddef.h>??
  • ?#include?<stdarg.h>??
  • ?#include?<string.h>??
  • ?#include?<assert.h>??
  • ?#include?<hiredis/hiredis.h>??
  • ???
  • ?void?doTest()??
  • ?{??
  • ?????int?timeout?=?10000;??
  • ?????struct?timeval?tv;??
  • ?????tv.tv_sec?=?timeout?/?1000;??
  • ?????tv.tv_usec?=?timeout?*?1000;??
  • ?????//以帶有超時(shí)的方式鏈接Redis服務(wù)器,同時(shí)獲取與Redis連接的上下文對(duì)象。??
  • ?????//該對(duì)象將用于其后所有與Redis操作的函數(shù)。??
  • ?????redisContext*?c?=?redisConnect((char*)"127.0.0.1",?6379);??
  • ?????if?(c->err)?{??
  • ?????????redisFree(c);??
  • ?????????return;??
  • ?????}??
  • ?????const?char*?command1?=?"set?stest1?value9";??
  • ?????redisReply*?r?=?(redisReply*)redisCommand(c,command1);??
  • ?????//需要注意的是,如果返回的對(duì)象是NULL,則表示客戶端和服務(wù)器之間出現(xiàn)嚴(yán)重錯(cuò)誤,必須重新鏈接。??
  • ?????//這里只是舉例說(shuō)明,簡(jiǎn)便起見(jiàn),后面的命令就不再做這樣的判斷了。??
  • ?????if?(NULL?==?r)?{??
  • ??????????redisFree(c);??
  • ?????????return;??
  • ?????}??
  • ?????//不同的Redis命令返回的數(shù)據(jù)類型不同,在獲取之前需要先判斷它的實(shí)際類型。??
  • ?????//至于各種命令的返回值信息,可以參考Redis的官方文檔,或者查看該系列博客的前幾篇??
  • ?????//有關(guān)Redis各種數(shù)據(jù)類型的博客。:)??
  • ?????//字符串類型的set命令的返回值的類型是REDIS_REPLY_STATUS,然后只有當(dāng)返回信息是"OK"??
  • ?????//時(shí),才表示該命令執(zhí)行成功。后面的例子以此類推,就不再過(guò)多贅述了。??
  • ?????if?(!(r->type?==?REDIS_REPLY_STATUS?&&?strcasecmp(r->str,"OK")?==?0))?{??
  • ?????????printf("Failed?to?execute?command[%s].\n",command1);??
  • ?????????freeReplyObject(r);??
  • ?????????redisFree(c);??
  • ?????????return;??
  • ?????}??
  • ?????//由于后面重復(fù)使用該變量,所以需要提前釋放,否則內(nèi)存泄漏。??
  • ?????freeReplyObject(r);??
  • ?????printf("Succeed?to?execute?command[%s].\n",command1);??
  • ???
  • ?????const?char*?command2?=?"strlen?stest1";??
  • ?????r?=?(redisReply*)redisCommand(c,command2);??
  • ?????if?(r->type?!=?REDIS_REPLY_INTEGER)?{??
  • ?????????printf("Failed?to?execute?command[%s].\n",command2);??
  • ?????????freeReplyObject(r);??
  • ?????????redisFree(c);??
  • ?????????return;??
  • ?????}??
  • ?????int?length?=?r->integer;??
  • ?????freeReplyObject(r);??
  • ?????printf("The?length?of?'stest1'?is?%d.\n",length);??
  • ?????printf("Succeed?to?execute?command[%s].\n",command2);??
  • ???
  • ?????const?char*?command3?=?"get?stest1";??
  • ?????r?=?(redisReply*)redisCommand(c,command3);??
  • ?????if?(r->type?!=?REDIS_REPLY_STRING)?{??
  • ?????????printf("Failed?to?execute?command[%s].\n",command3);??
  • ?????????freeReplyObject(r);??
  • ?????????redisFree(c);??
  • ?????????return;??
  • ?????}??
  • ?????printf("The?value?of?'stest1'?is?%s.\n",r->str);??
  • ?????freeReplyObject(r);??
  • ?????printf("Succeed?to?execute?command[%s].\n",command3);??
  • ???
  • ?????const?char*?command4?=?"get?stest2";??
  • ?????r?=?(redisReply*)redisCommand(c,command4);??
  • ?????//這里需要先說(shuō)明一下,由于stest2鍵并不存在,因此Redis會(huì)返回空結(jié)果,這里只是為了演示。??
  • ?????if?(r->type?!=?REDIS_REPLY_NIL)?{??
  • ?????????printf("Failed?to?execute?command[%s].\n",command4);??
  • ?????????freeReplyObject(r);??
  • ?????????redisFree(c);??
  • ?????????return;??
  • ?????}??
  • ?????freeReplyObject(r);??
  • ?????printf("Succeed?to?execute?command[%s].\n",command4);??
  • ???
  • ?????const?char*?command5?=?"mget?stest1?stest2";??
  • ?????r?=?(redisReply*)redisCommand(c,command5);??
  • ?????//不論stest2存在與否,Redis都會(huì)給出結(jié)果,只是第二個(gè)值為nil。??
  • ?????//由于有多個(gè)值返回,因?yàn)榉祷貞?yīng)答的類型是數(shù)組類型。??
  • ?????if?(r->type?!=?REDIS_REPLY_ARRAY)?{??
  • ?????????printf("Failed?to?execute?command[%s].\n",command5);??
  • ?????????freeReplyObject(r);??
  • ?????????redisFree(c);??
  • ?????????//r->elements表示子元素的數(shù)量,不管請(qǐng)求的key是否存在,該值都等于請(qǐng)求是鍵的數(shù)量。??
  • ?????????assert(2?==?r->elements);??
  • ?????????return;??
  • ?????}??
  • ?????int?i;??
  • ??????for?(i?=?0;?i?<?r->elements;?++i)?{??
  • ?????????redisReply*?childReply?=?r->element[i];??
  • ?????????//之前已經(jīng)介紹過(guò),get命令返回的數(shù)據(jù)類型是string。??
  • ?????????//對(duì)于不存在key的返回值,其類型為REDIS_REPLY_NIL。??
  • ?????????if?(childReply->type?==?REDIS_REPLY_STRING)??
  • ?????????????printf("The?value?is?%s.\n",childReply->str);??
  • ?????}??
  • ?????//對(duì)于每一個(gè)子應(yīng)答,無(wú)需使用者單獨(dú)釋放,只需釋放最外部的redisReply即可。??
  • ?????freeReplyObject(r);??
  • ?????printf("Succeed?to?execute?command[%s].\n",command5);??
  • ???
  • ?????printf("Begin?to?test?pipeline.\n");??
  • ?????//該命令只是將待發(fā)送的命令寫(xiě)入到上下文對(duì)象的輸出緩沖區(qū)中,直到調(diào)用后面的??
  • ?????//redisGetReply命令才會(huì)批量將緩沖區(qū)中的命令寫(xiě)出到Redis服務(wù)器。這樣可以??
  • ?????//有效的減少客戶端與服務(wù)器之間的同步等候時(shí)間,以及網(wǎng)絡(luò)IO引起的延遲。??
  • ?????//至于管線的具體性能優(yōu)勢(shì),可以考慮該系列博客中的管線主題。??
  • ????/*?if?(REDIS_OK?!=?redisAppendCommand(c,command1)?
  • ?????????||?REDIS_OK?!=?redisAppendCommand(c,command2)?
  • ?????????||?REDIS_OK?!=?redisAppendCommand(c,command3)?
  • ?????????||?REDIS_OK?!=?redisAppendCommand(c,command4)?
  • ?????????||?REDIS_OK?!=?redisAppendCommand(c,command5))?{?
  • ?????????redisFree(c);?
  • ?????????return;?
  • ?????}?
  • ?*/??
  • ??
  • ????redisAppendCommand(c,command1);??
  • ????redisAppendCommand(c,command2);??
  • ????redisAppendCommand(c,command3);??
  • ????redisAppendCommand(c,command4);??
  • ????redisAppendCommand(c,command5);??
  • ?????redisReply*?reply?=?NULL;??
  • ?????//對(duì)pipeline返回結(jié)果的處理方式,和前面代碼的處理方式完全一直,這里就不再重復(fù)給出了。??
  • ?????if?(REDIS_OK?!=?redisGetReply(c,(void**)&reply))?{??
  • ?????????printf("Failed?to?execute?command[%s]?with?Pipeline.\n",command1);??
  • ?????????freeReplyObject(reply);??
  • ?????????redisFree(c);??
  • ?????}??
  • ?????freeReplyObject(reply);??
  • ?????printf("Succeed?to?execute?command[%s]?with?Pipeline.\n",command1);??
  • ???
  • ?????if?(REDIS_OK?!=?redisGetReply(c,(void**)&reply))?{??
  • ?????????printf("Failed?to?execute?command[%s]?with?Pipeline.\n",command2);??
  • ?????????freeReplyObject(reply);??
  • ?????????redisFree(c);??
  • ?????}??
  • ?????freeReplyObject(reply);??
  • ?????printf("Succeed?to?execute?command[%s]?with?Pipeline.\n",command2);??
  • ???
  • ?????if?(REDIS_OK?!=?redisGetReply(c,(void**)&reply))?{??
  • ?????????printf("Failed?to?execute?command[%s]?with?Pipeline.\n",command3);??
  • ?????????freeReplyObject(reply);??
  • ?????????redisFree(c);??
  • ?????}??
  • ?????freeReplyObject(reply);??
  • ?????printf("Succeed?to?execute?command[%s]?with?Pipeline.\n",command3);??
  • ???
  • ?????if?(REDIS_OK?!=?redisGetReply(c,(void**)&reply))?{??
  • ?????????printf("Failed?to?execute?command[%s]?with?Pipeline.\n",command4);??
  • ?????????freeReplyObject(reply);??
  • ?????????redisFree(c);??
  • ?????}??
  • ?????freeReplyObject(reply);??
  • ?????printf("Succeed?to?execute?command[%s]?with?Pipeline.\n",command4);??
  • ???
  • ?????if?(REDIS_OK?!=?redisGetReply(c,(void**)&reply))?{??
  • ?????????printf("Failed?to?execute?command[%s]?with?Pipeline.\n",command5);??
  • ?????????freeReplyObject(reply);??
  • ?????????redisFree(c);??
  • ?????}??
  • ?????freeReplyObject(reply);??
  • ?????printf("Succeed?to?execute?command[%s]?with?Pipeline.\n",command5);??
  • ?????//由于所有通過(guò)pipeline提交的命令結(jié)果均已為返回,如果此時(shí)繼續(xù)調(diào)用redisGetReply,??
  • ?????//將會(huì)導(dǎo)致該函數(shù)阻塞并掛起當(dāng)前線程,直到有新的通過(guò)管線提交的命令結(jié)果返回。??
  • ?????//最后不要忘記在退出前釋放當(dāng)前連接的上下文對(duì)象。??
  • ?????redisFree(c);??
  • ?????return;??
  • ?}??
  • ???
  • ?int?main()??
  • ?{??
  • ?????doTest();??
  • ?????return?0;??
  • ?}??

  • 述文件命名為:mytest.c

    [root@loalhost hj]# gcc mytest.c -o mytest -lhiredis
    [root@localhost hj]# ./mytest?
    Succeed to execute command[set stest1 value9].
    The length of 'stest1' is 6.
    Succeed to execute command[strlen stest1].
    The value of 'stest1' is value9.
    Succeed to execute command[get stest1].
    Succeed to execute command[get stest2].
    The value is value9.
    Succeed to execute command[mget stest1 stest2].
    Begin to test pipeline.
    Succeed to execute command[set stest1 value9] with Pipeline.
    Succeed to execute command[strlen stest1] with Pipeline.
    Succeed to execute command[get stest1] with Pipeline.
    Succeed to execute command[get stest2] with Pipeline.
    Succeed to execute command[mget stest1 stest2] with Pipeline.

    ?

    ?

    參考網(wǎng)址:

    http://tech.it168.com/a2011/0830/1239/000001239923_all.shtml

    http://www.cnblogs.com/stephen-liu74/category/354125.html

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

    總結(jié)

    以上是生活随笔為你收集整理的Redis:安装、配置、操作和简单代码实例(C语言Client端)[转]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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