redis for windows之nosql還需要入門?


  RT:nosql給很多人的感覺就是上手特別快,本文也是一篇入門級的,哎~~ 又寫了一篇沒有卵用的博文,姑且把它當作一篇文檔吧,還是沒有發布/訂閱、事件...等介紹的一篇殘缺文檔,幸好廢話不是很多,湊合着看吧。

一、redis之啟動配置

  1、下載,MS團隊為windows移植來的redis

      https://github.com/MSOpenTech/redis/releases

  2、啟動和結束

--啟動redis服務
E:\redis>redis-server.exe redis.windows.conf
--結束redis服務
127.0.0.1:6379> shutdown
not connected>

  3、修改配置文件的兩種方式

     3.1、運行中使用config set命令修改

--連接redis,-h <ip> -a <pwd>
E:\redis>redis-cli.exe -h 127.0.0.1
--測試redis是否正常工作
127.0.0.1:6379> ping pong
"pong"
--設置密碼為xxx,服務器在外網還是設置上吧,貌似有不少公司都不設置
127.0.0.1:6379> config set requirepass 123
OK
--獲取密碼的時候就提示沒權限了
127.0.0.1:6379> config get requirepass
(error) NOAUTH Authentication required.
--使用auth命令認證
127.0.0.1:6379> auth 123
OK
127.0.0.1:6379> config get save
1) "save"
2) "jd 900 jd 300 jd 60"
--清空持久化,只做緩存處理的話關閉(尤其配置低的服務器),持久化一次redis就可能無響應了,日志文件也不會記錄
127.0.0.1:6379> config set save ""
OK
--保存創建rdb備份文件,redis:DB saved on disk
127.0.0.1:6379> save
OK
--后台save,redis:*Background saving started by pid 1968 # fork operation complete* Background saving terminated with success
127.0.0.1:6379> bgsave
Background saving started
--獲取rdb文件路徑,恢復備份直接覆蓋重啟redis即可
127.0.0.1:6379> config get dir
1) "dir"
2) "E:\\redis"

     3.2、redis.windows.conf 用記事本打開直接修改保存。

################################ 普通  #####################################
port 6379  --redis的監聽端口
tcp-backlog 511  --默認就好
timeout 0  --客戶端連接空閑幾秒鍾后關閉,0為禁用不關閉
tcp-keepalive 0  --向客戶端發送ACK的時間隔(單位/秒),0為不發送
loglevel notice  --記錄日志級別(debug、verbose、notice、warning)
logfile "redis-log.txt"  --日志文件名,為空就是輸出控制台,指定文件啟動后會寫入文件中
#syslog-enabled no  --是否啟動windows事件日志
#syslog-ident redis  --標注事件來源是redis
databases 16  --數據庫數量
################################ 快照  ################################
save <seconds> <changes>  --在指定秒數和數據變化次數后保存到磁盤,不需持久化注釋即可
stop-writes-on-bgsave-error yes  --停止-寫入-在-后台寫入-錯誤時 yes or no,字面意思
rdbcompression yes --壓縮redis的rdb數據文件?
rdbchecksum yes  --rdb校驗,性能消耗10%,需提高性能時可跳過
dbfilename dump.rdb  --持久化的數據文件名
dir ./  --工作目錄,conf和exe同文件夾
################################# 主從 #################################
#slaveof <masterip> <masterport>  --從庫,通過主庫ip、端口備份
#masterauth <master-password>  --主庫連接密碼
slave-serve-stale-data yes  --與主庫失去連接時,是否允許客戶端獲取數據?
slave-read-only yes  --從庫只讀?
repl-diskless-sync no  --啟動無盤復制?磁盤讀寫差並且帶寬高 yes
repl-diskless-sync-delay 5  --無盤同步延遲秒數
#repl-ping-slave-period 10  --向主庫發送ping請求間隔秒數
#repl-timeout 60  --ping超時
repl-disable-tcp-nodelay no  --延遲將會減少但要使用更多的帶寬?
#repl-backlog-size 1mb  --同步backlog增量
#repl-backlog-ttl 3600  --backlog緩沖釋放秒數,0為不釋放
slave-priority 100  --當主庫不工作時,提升從庫為主庫的優先級
#min-slaves-to-write 3  --最小幾個延遲
#min-slaves-max-lag 10  --最小延遲秒數
################################# 安全 #################################
#requirepass <password> --密碼
#rename-command CONFIG ""  --重命名命令
################################### LIMITS ####################################
#maxclients 10000  --最大連接數
#maxheap <bytes>  --fork()持久化時映射文件的最大數
#heapdir <directory path(absolute or relative)>  --堆內存映射的本地路徑
#persistence-available [(yes)|no]  --是否關閉所有持久化
#maxmemory <bytes>  --最大內存
#maxmemory-policy volatile-lru  --內存極致時,根據哪種機制刪除key
#maxmemory-samples 3  --樣本key的個數,從中刪除最舊的
################################# 追加模式 #################################
appendonly no  --如果AOF開啟,那么在啟動時Redis將加載AOF文件
appendfsync everysec 
--no:不要立刻刷,只有在操作系統需要刷的時候再刷。比較快。
--always:每次寫操作都立刻寫入到aof文件。慢,但是最安全。
--everysec:每秒寫一次。折中方案。
no-appendfsync-on-rewrite no  --這個設置成"yes"帶來了延遲問題,就保持"no",這是保存持久數據的最安全的方式
auto-aof-rewrite-percentage 100  --超過百分比 觸發重新操作
auto-aof-rewrite-min-size 64mb  --設置被重新日志的最小尺寸
aof-load-truncated yes  --AOF文件被發現壞損,redis將拒絕訪問終止?
################################ LUA SCRIPTING  ###############################
lua-time-limit 5000  --腳本的最大執行時間,毫秒為單位
################################## SLOW LOG ###################################
slowlog-log-slower-than 10000  --記錄慢查詢超時時長 單位微秒
slowlog-max-len 128  --慢查詢日志長度
################################ LATENCY MONITOR ##############################
latency-monitor-threshold 0  --延遲控制閥數值 毫秒
############################# Event notification ##############################
notify-keyspace-events ""  --通知 Pub/Sub 客戶端關於鍵空間發生的事件
############################### ADVANCED CONFIG ###############################
--當hash只有少量的entry時,並且最大的entry所占空間沒有超過指定的限制時,會用一種節省內存的數據結構來編碼。可以通過下面的指令來設定限制
hash-max-ziplist-entries 512 
hash-max-ziplist-value 64
--與hash似,數據元素較少的list,可以用另一種方式來編碼從而節省大量空間。這種特殊的方式只有在符合下面限制時才可以用:
list-max-ziplist-entries 512
list-max-ziplist-value 64
--set有一種特殊編碼的情況:當set數據全是十進制64位有符號整型數字構成的字符串時。下面這個配置項就是用來設置set使用這種編碼來節省內存的最大長度。
set-max-intset-entries 512
--與hash和list相似,有序集合也可以用一種特別的編碼方式來節省大量空間。這種編碼只適合長度和元素都小於下面限制的有序集合:
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
--HyperLogLog稀疏表示字節的限制。限制包括16字節的頭。當HyperLogLog使用稀疏表示十字架此限制,它被轉換成致密表示。16000更大的值是完全無用的,因為在這一點上密集的表示是更多的內存效率。的建議值是〜3000,以便具有的優點空間高效的編碼,而不會減慢太多PFADD,這是O(N)與稀疏編碼。該值可提高到〜10000時CPU不是一個問題,但空間,並且該數據集是由許多HyperLogLogs與在基數0 - 15000的范圍。
hll-sparse-max-bytes 3000
--對延遲比較在意,不能夠接受Redis時不時的對請求有2毫秒的延遲的話,就用"activerehashing no",如果不太在意延遲而希望盡快釋放內存就設置"activerehashing yes"
activerehashing yes
--范圍是1到500之間,但是值超過100通常不是一個好主意。大多數用戶應該使用10這個默認值,只有在非常低的延遲要求時有必要提高到100。
hz 10
--當一個子進程重寫AOF文件時,如果啟用下面的選項,則文件每生成32M數據會被同步。為了增量式的寫入硬盤並且避免大的延遲高峰這個指令是非常有用的
aof-rewrite-incremental-fsync yes

二、redis之數據格式

  1、redis數據類型(參考:http://www.redis.cn/topics/data-types-intro.html#strings)

--字符串
--Redis字符串是字節序列。Redis字符串是二進制安全的,這意味着他們有一個已知的長度沒有任何特殊字符終止,所以你可以存儲任何東西,512兆為上限。
127.0.0.1:6379> set mykey "redis"
OK
127.0.0.1:6379> get mykey
"redis"

--哈希
--Redis的哈希是鍵值對的集合。 Redis的哈希值是字符串字段和字符串值之間的映射,因此它們被用來表示對象
127.0.0.1:6379> hmset user:1 uname "lily" key1 value1 key2 value2
OK
127.0.0.1:6379> hgetall user:1
1) "uname"
2) "lily"
3) "key1"
4) "value1"
5) "key2"
6) "value2"

--列表
--LPUSH 命令可向list的左邊(頭部)添加一個新元素,而RPUSH命令可向list的右邊(尾部)添加一個新元素。最后LRANGE 命令可從list中取出一定范圍的元素
127.0.0.1:6379> rpush mylist a
(integer) 2
127.0.0.1:6379> rpush mylist b
(integer) 3
127.0.0.1:6379> lpush mylist c
(integer) 4
127.0.0.1:6379> lrange mylist 1
(error) ERR wrong number of arguments for 'lrange' command
127.0.0.1:6379> lrange mylist 0 1
1) "c"
2) "123"
127.0.0.1:6379>

--集合
--Redis的集合是字符串的無序集合。在Redis您可以添加,刪除和測試文件是否存在,在成員O(1)的時間復雜度
127.0.0.1:6379> sadd myset 1 2 3 4
(integer) 4
127.0.0.1:6379> smembers myset
1) "1"
2) "2"
3) "3"
4) "4"

--有序集合
--Redis的有序集合類似於Redis的集合,字符串不重復的集合。不同的是,一個有序集合的每個成員用分數,以便采取有序set命令,從最小的到最大的成員分數有關。雖然成員具有唯一性,但分數可能會重復
127.0.0.1:6379> zadd myzset 0 "an"
(integer) 1
127.0.0.1:6379> zadd myzset 1 "kc" 2 "bi"
(integer) 2
127.0.0.1:6379> zrange myzset 0 -1
1) "an"
2) "kc"
3) "bi"

--bit
--與sqlserver bit類型類似,存儲0 1值
127.0.0.1:6379> set bitkey 0
OK
127.0.0.1:6379> set bitkey1 1
OK
127.0.0.1:6379> get bitkey
"0"

--HyperLogLog
--Redis 在 2.8.9 版本添加了 HyperLogLog 結構。
--Redis HyperLogLog 是用來做基數統計的算法,HyperLogLog 的優點是,在輸入元素的數量或者體積非常非常大時,計算基數所需的空間總是固定 的、並且是很小的。
--在 Redis 里面,每個 HyperLogLog 鍵只需要花費 12 KB 內存,就可以計算接近 2^64 個不同元素的基 數。這和計算基數時,元素越多耗費內存就越多的集合形成鮮明對比。
--但是,因為 HyperLogLog 只會根據輸入元素來計算基數,而不會儲存輸入元素本身,所以 HyperLogLog 不能像集合那樣,返回輸入的各個元素。
127.0.0.1:6379> pfadd hllkey "c sharp" "c++" "java" "object-c"
(integer) 1
127.0.0.1:6379> pfcount hllkey
(integer) 4

--GEOADD
--將指定的地理空間位置(緯度、經度、名稱)添加到指定的key中。這些數據將會存儲到sorted set這樣的目的是為了方便使用GEORADIUS或者GEORADIUSBYMEMBER命令對數據進行半徑查詢等操作
--該命令以采用標准格式的參數x,y,所以經度必須在緯度之前。這些坐標的限制是可以被編入索引的,區域面積可以很接近極點但是不能索引。具體的限制,由EPSG:900913 / EPSG:3785 / OSGEO:41001 規定如下:
----有效的經度從-180度到180度。
----有效的緯度從-85.05112878度到85.05112878度。
--當坐標位置超出上述指定范圍時,該命令將會返回一個錯誤。
redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2
redis> GEODIST Sicily Palermo Catania
"166274.15156960039"
redis> GEORADIUS Sicily 15 37 100 km
1) "Catania"
redis> GEORADIUS Sicily 15 37 200 km
1) "Palermo"
2) "Catania"

三、Redis之事物

--開啟一個事物
127.0.0.1:6379> multi
OK
--操作不會立即執行,會被放入事物隊列中
127.0.0.1:6379> set stringkey1 one
QUEUED
127.0.0.1:6379> set stringkey2 two
QUEUED
127.0.0.1:6379> set stringkey3 three
QUEUED
--通過exec執行,可通過discard清空事物隊列中等待執行的操作,放棄執行事務
127.0.0.1:6379> exec
1) OK
2) OK
3) OK

四、redis之StackExchange

  雖然ServiceStack從v4開始就變成商業版本了,不妨還有大量的公司在使用,但是相關的文章大家已經寫爛了,所以就來寫寫另外一個用於NET訪問Redis的Client--StackExchange。當然也有不少人對它的穩定性、性能方面持有顧慮,我還沒有使用它的大數據項目經驗,但是Microsoft.Web.RedisSessionStateProvider庫底層都基於StackExchange訪問Redis處理web session的分布式存儲了,那我們也不需要過多的糾結了,兵來將擋水來土掩。

  感受MS提供的分布式存儲session,戳此鏈接:http://www.cnblogs.com/NotAnEmpty/p/5459977.html

  安裝:

PM> Install-Package StackExchange.Redis

  1、連接及配置

//1.1 Connect
//使用連接字符串或者ConfigurationOptions對象連接redis,作者把ConnectionMultiplexer設計為共享和重用,並且線程安全,所以共用一個實例就可以了
string connstr = "127.0.0.1:6379,allowadmin=true";
ConnectionMultiplexer conn = ConnectionMultiplexer.Connect(connstr);
ConfigurationOptions options = ConfigurationOptions.Parse(connstr);
string parsestr = options.ToString();
//ConnectionMultiplexer conn = ConnectionMultiplexer.Connect(new ConfigurationOptions() {
//    EndPoints = { "127.0.0.1:6379" }
//});

//1.2 GetDatabase
//通過GetDatabase(int db = -1, object asyncState = null)穿入數據庫ID獲取數據庫對象,異步操作需傳入Task.AsyncState
IDatabase db = conn.GetDatabase(0);

   ConfigurationOptions by translate.google

//獲取或設置是否連接/配置超時應明確通知,通過一個TimeoutException
public bool AbortOnConnectFail { get; set; }

//指示管理操作是否應該被允許
public bool AllowAdmin { get; set; }

//自動編碼和解碼信道
public RedisChannel ChannelPrefix { get; set; }

//客戶端名稱用於所有連接
public string ClientName { get; set; }

//與此配置相關聯的命令的地圖
public CommandMap CommandMap { get; set; }

//檢查每n秒(每分鍾默認情況下)的配置
public int ConfigCheckSeconds { get; set; }

//通道用於廣播和偵聽配置更改通知
public string ConfigurationChannel { get; set; }

//次數重復初始連接循環,如果沒有服務器響應及時
public int ConnectRetry { get; set; }

//指定應允許連接的毫秒數
public int ConnectTimeout { get; set; }

//指定默認數據庫調用ConnectionMultiplexer.GetDatabase時使用()不帶任何參數
public int? DefaultDatabase { get; set; }

//服務器默認版本
public Version DefaultVersion { get; set; }

//端點此配置定義
public EndPointCollection EndPoints { get; }

//指定在該連接應被ping通,以確保秒時間有效性
public int KeepAlive { get; set; }

//使用的口令與服務器進行身份驗證
public string Password { get; set; }

//指示管理操作是否應該被允許
public Proxy Proxy { get; set; }

//指示是否應該端點通過DNS連接之前得到解決
public bool ResolveDns { get; set; }

 //指定以毫秒為單位的時間,該系統應允許響應得出的結論是插座是不健康(默認為SyncTimeout)前
public int ResponseTimeout { get; set; }

 //獲取或設置SocketManager實例與這些選項一起使用;如果這為null每個復用器SocketManager自動創建。
public SocketManager SocketManager { get; set; }

//指示連接是否應該加密
public bool Ssl { get; set; }

//目標主機,以驗證SSL證書時使用;在這里設置一個值 啟用SSL模式
public string SslHost { get; set; }

//指定以毫秒為單位,該系統應允許同步時間操作(默認為1秒)
public int SyncTimeout { get; set; }

//指示連接是否應該加密
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Please use .Ssl instead of .UseSsl")]
public bool UseSsl { get; set; }

//輸出緩沖區的大小使用
public int WriteBuffer { get; set; }

  2、API

    2.1 string

//2.1.1 set
//key-val存儲
//bool StringSet(RedisKey key, RedisValue value, TimeSpan? expiry = default(TimeSpan?), When when = When.Always, CommandFlags flags = CommandFlags.None);
bool stringsetResult = db.StringSet("mykey", "myvalue", TimeSpan.FromHours(1), When.Always, CommandFlags.None);

//key-val組存儲
//bool StringSet(KeyValuePair<RedisKey, RedisValue>[] values, When when = When.Always, CommandFlags flags = CommandFlags.None);
db.StringSet(new KeyValuePair<RedisKey, RedisValue>[] { new KeyValuePair<RedisKey, RedisValue>("mykey", "myvalue") });

//追加值,返回追加后長度
//long StringAppend(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None);
long appendlong = db.StringAppend("mykey", "|myvalue");

//偏移量存儲
//RedisValue StringSetRange(RedisKey key, long offset, RedisValue value, CommandFlags flags = CommandFlags.None);
db.StringSetRange("myrangekey", 3, "myrangevalue"); //值:___myrangevalue

//增量存儲,與StringDecrement相反
//long StringIncrement(RedisKey key, long value = 1, CommandFlags flags = CommandFlags.None);
//double StringIncrement(RedisKey key, double value, CommandFlags flags = CommandFlags.None);
db.StringSet("intkey", 10);
db.StringIncrement("intkey", 2); //value:12

//2.1.2 get
//根據key獲取val
//RedisValue StringGet(RedisKey key, CommandFlags flags = CommandFlags.None);
RedisValue rvalue = db.StringGet("mykey");
//rvalue.IsNull 是否null

//獲取一組val
//RedisValue[] StringGet(RedisKey[] keys, CommandFlags flags = CommandFlags.None);
RedisValue[] rvalues = db.StringGet(new RedisKey[] { "mykey" });

//把存儲的string substring后返回
//RedisValue StringGetRange(RedisKey key, long start, long end, CommandFlags flags = CommandFlags.None);
RedisValue rangevalue = db.StringGetRange("mykey", 0, 1); //返回my

//存儲新值,返回舊值
//RedisValue StringGetSet(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None);
RedisValue oldval = db.StringGetSet("key1", "val2");


//2.1.3 other
//獲取帶有過期時間的val
//RedisValueWithExpiry StringGetWithExpiry(RedisKey key, CommandFlags flags = CommandFlags.None);
RedisValueWithExpiry rvalwithxp = db.StringGetWithExpiry("mykey");

//獲取length
//long StringLength(RedisKey key, CommandFlags flags = CommandFlags.None);
long vallength = db.StringLength("mykey");

    2.2 hash

//2.1.1 set
//bool HashSet(RedisKey key, RedisValue hashField, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None);
db.HashSet("hashkey1", "name", "lily");
//void HashSet(RedisKey key, HashEntry[] hashFields, CommandFlags flags = CommandFlags.None);
db.HashSet("hashkey2", new HashEntry[] { new HashEntry("name", "lucy"), new HashEntry("age", 18) });


//2.1.2 get
//RedisValue HashGet(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None);
RedisValue rhashval = db.HashGet("hashkey1", "name");
//RedisValue[] HashGet(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None);
RedisValue[] rhashvals = db.HashGet("hashkey2", new RedisValue[] { "name", "age" });
//HashEntry[] HashGetAll(RedisKey key, CommandFlags flags = CommandFlags.None);
HashEntry[] hashentitrys = db.HashGetAll("hashkey2");

//long HashIncrement(RedisKey key, RedisValue hashField, long value = 1, CommandFlags flags = CommandFlags.None);
//double HashIncrement(RedisKey key, RedisValue hashField, double value, CommandFlags flags = CommandFlags.None);
db.HashIncrement("hashkey2", "age", 3);


//2.1.3 other
//key所對應的hash字段是否存在
//bool HashExists(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None);
db.HashExists("hashkey1", "name");

//key所對應的hash字段個數
//long HashLength(RedisKey key, CommandFlags flags = CommandFlags.None);
db.HashLength("hashkey1");

//key所對應的所有hash字段
//RedisValue[] HashKeys(RedisKey key, CommandFlags flags = CommandFlags.None);
db.HashKeys("hashkey2");

//根據pattern(pattern參考:http://redis.io/commands/keys)掃描key所對應的字段值,可指定掃描頁數、開始和偏移量
//IEnumerable<HashEntry> HashScan(RedisKey key, RedisValue pattern, int pageSize, CommandFlags flags);
db.HashScan("hashkey2");
foreach (HashEntry item in db.HashScan("hashkey2","age",10))
{
    Console.WriteLine("{0}:{1}", item.Name, item.Value);
}

//刪除,返回 true/false 或者 刪除字段值的個數
//bool HashDelete(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None);
db.HashDelete("hashkey1", "name");
//long HashDelete(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None);
db.HashDelete("hashkey2", new RedisValue[] { "name", "age" });

    2.3 list

//2.3.1 push
 //從頭部入列
 //long ListLeftPush(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None);
 db.ListLeftPush("listkey1", "top");
 //入列多個,top1在最上
 //long ListLeftPush(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None);
 db.ListLeftPush("listkey1", new RedisValue[] { "top3", "top1" });

 //從尾部入列
 //long ListRightPush(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None);
 db.ListRightPush("listkey1", "bottom");
 //入列多個,buttom3在最下
 //long ListRightPush(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None);
 db.ListRightPush("listkey1", new RedisValue[] { "bottom1", "bottom3" });

 //在xx之后入列
 //long ListInsertAfter(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None);
 db.ListInsertAfter("listkey1", "top1", "top2");

 //在xx之前入列
 //long ListInsertBefore(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None);
 db.ListInsertBefore("listkey1", "bottom3", "bottom2");

 //從第幾個后面入列,第4個為top(top1 top2 top3 top bottom bottom1 bottom2 bottom3)
 //void ListSetByIndex(RedisKey key, long index, RedisValue value, CommandFlags flags = CommandFlags.None);
 db.ListSetByIndex("listkey1", 4, "middle");


 //2.3.2 pop
 //從上出列 top1
 //RedisValue ListLeftPop(RedisKey key, CommandFlags flags = CommandFlags.None);
 db.ListLeftPop("listkey1");

 //從下出列 bottom3
 //RedisValue ListRightPop(RedisKey key, CommandFlags flags = CommandFlags.None);
 db.ListRightPop("listkey1");

 //根據index獲取(下標0開始) 3為middle,之前從上出列了一個top1
 //RedisValue ListGetByIndex(RedisKey key, long index, CommandFlags flags = CommandFlags.None);
 db.ListGetByIndex("listkey1", 3);

 //獲取range
 //RedisValue[] ListRange(RedisKey key, long start = 0, long stop = -1, CommandFlags flags = CommandFlags.None);
 foreach (RedisValue item in db.ListRange("listkey1", 0, 3))
 {
     Console.WriteLine(item);
 }


 //2.3.2 other
 //獲取list的length
 //long ListLength(RedisKey key, CommandFlags flags = CommandFlags.None);
 db.ListLength("listkey1");

 //截取范圍保留
 //void ListTrim(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None);
 db.ListTrim("listkey1", 3, 4);

 //刪除,返回刪除成功個數
 //long ListRemove(RedisKey key, RedisValue value, long count = 0, CommandFlags flags = CommandFlags.None);
 db.ListRemove("listkey1", "middle");

    2.4 set

//2.4.1 add
//如果value重復,將被忽略不添加
//bool SetAdd(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None);
db.SetAdd("setkey", 1);
//long SetAdd(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None);
db.SetAdd("setkey", new RedisValue[] { 1, 2, 3, 4, 5 });
db.SetAdd("setkey2", new RedisValue[] { 5, 6, 7, 8 });

//2.4.2 get
//獲取集合內所有元素
//RedisValue[] SetMembers(RedisKey key, CommandFlags flags = CommandFlags.None);
RedisValue[] vals = db.SetMembers("setkey2");


//2.4.3 remove
//移除單個val
//long SetRemove(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None);
db.SetRemove("setkey2", 7);
//移除多個val,返回成功個數
//bool SetRemove(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None);
db.SetRemove("setkey2", new RedisValue[] { 7, 8 });


//2.4.4 Combine
//對兩個集合合並操作
//RedisValue[] SetCombine(SetOperation operation, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None);
var keyvals = db.SetCombine(SetOperation.Union, "setkey", "setkey2");
Console.WriteLine(string.Join(",", keyvals));
//RedisValue[] SetCombine(SetOperation operation, RedisKey[] keys, CommandFlags flags = CommandFlags.None);
db.SetCombine(SetOperation.Union, new RedisKey[] { "setkey", "setkey2" });

//合並后返回
//long SetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None);
RedisValue[] rvals = db.SetCombine(SetOperation.Union, "setkey", "setkey2");
//合並后直存儲,,返回val的數量
//long SetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey[] keys, CommandFlags flags = CommandFlags.None);
db.SetCombineAndStore(SetOperation.Union, "setkeycombine", new RedisKey[] { "setkey", "setkey2" });
Console.WriteLine(string.Join(",", db.SetMembers("setkeycombine")));


//2.4.5 other
//scan pattern參考:http://redis.io/commands/keys
//IEnumerable<RedisValue> SetScan(RedisKey key, RedisValue pattern, int pageSize, CommandFlags flags);
db.SetAdd("setkey3", new RedisValue[] { "four", "one", "two", "three" });
foreach (RedisValue item in db.SetScan("setkey3", "*o*", 10, CommandFlags.None))
{
    Console.WriteLine(item);
}

//是否包含該val
//bool SetContains(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None);
db.SetContains("setkeycombine", 7);

//集合length
//long SetLength(RedisKey key, CommandFlags flags = CommandFlags.None);
db.SetLength("setkeycombine");

//把val從一個set移動到另一個set,目標set不存在則新建
//bool SetMove(RedisKey source, RedisKey destination, RedisValue value, CommandFlags flags = CommandFlags.None);
db.SetMove("setkey", "toset", 1);

//隨機移除並返回一個val
//RedisValue SetPop(RedisKey key, CommandFlags flags = CommandFlags.None);
db.SetPop("setkey");

//隨機返回 但不移除,可指定返回數量
//RedisValue SetRandomMember(RedisKey key, CommandFlags flags = CommandFlags.None);
db.SetRandomMember("setkey");
//RedisValue[] SetRandomMembers(RedisKey key, long count, CommandFlags flags = CommandFlags.None);
db.SetRandomMembers("setkey", 3);

    2.5 zset

//2.5.1 add 重復則忽略
//bool SortedSetAdd(RedisKey key, RedisValue member, double score, CommandFlags flags = CommandFlags.None);
db.SortedSetAdd("zsetkey", "日本", 101);
db.SortedSetAdd("zsetkey", "韓國", 102);
//long SortedSetAdd(RedisKey key, SortedSetEntry[] values, CommandFlags flags = CommandFlags.None);
db.SortedSetAdd("zsetkey1", new SortedSetEntry[] { new SortedSetEntry("巴西", 0), new SortedSetEntry("意大利", 1), new SortedSetEntry("阿根廷", 2), new SortedSetEntry("英格蘭", 3), });


//2.5.2 get 
//排序獲取,下標從0開始
//RedisValue[] SortedSetRangeByRank(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None);
RedisValue[] rvals = db.SortedSetRangeByRank("newzsetkey", 0, 2, Order.Ascending, CommandFlags.None);
Console.WriteLine(string.Join(",", rvals));
//和上面一個卵用,只不過返回了SortedSetEntry數組,有了score屬性
//SortedSetEntry[] SortedSetRangeByRankWithScores(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None);
foreach (SortedSetEntry item in db.SortedSetRangeByRankWithScores("newzsetkey", 0, 2, Order.Ascending, CommandFlags.None))
{
    Console.WriteLine("{0}:{1}", item.Element, item.Score);
}
//根據score獲取,skip、take分頁獲取
//RedisValue[] SortedSetRangeByScore(RedisKey key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None);
RedisValue[] rvalsbyscore = db.SortedSetRangeByScore("newzsetkey", 2, 4, Exclude.None, Order.Ascending, 0, 10, CommandFlags.None);
//根據score獲取,帶score屬性
//SortedSetEntry[] SortedSetRangeByScoreWithScores(RedisKey key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None);
SortedSetEntry[] entitys = db.SortedSetRangeByScoreWithScores("newzsetkey", 2, 4, Exclude.None, Order.Ascending, 0, 10, CommandFlags.None);
//在同一score的zset中獲取一定范圍的元素
//RedisValue[] SortedSetRangeByValue(RedisKey key, RedisValue min = default(RedisValue), RedisValue max = default(RedisValue), Exclude exclude = Exclude.None, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None);
RedisValue[] rvalsbyval = db.SortedSetRangeByValue("newzsetkey", 2, 4, Exclude.None, 0, 10, CommandFlags.None);

//返回元素的score,不存在返回0
//double? SortedSetScore(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None);
db.SortedSetScore("zsetkey1", "美國");


//2.5.3 del
//根據val刪
//bool SortedSetRemove(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None);
db.SortedSetRemove("zsetkey", "意大利");
//long SortedSetRemove(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None);
db.SortedSetRemove("zsetkey", new RedisValue[] { "意大利", "美國" });

//根據下標范圍刪
//long SortedSetRemoveRangeByRank(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None);
db.SortedSetRemoveRangeByRank("zsetkey", 0, 2);
//根據score刪
//long SortedSetRemoveRangeByScore(RedisKey key, double start, double stop, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None);
db.SortedSetRemoveRangeByScore("zsetkey", 2, 4);
//在同一score的zset中根據下標刪
//long SortedSetRemoveRangeByValue(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None);
db.SortedSetRemoveRangeByValue("zsetkey", 2, 4);

//2.5.4 combine
//合並操作 返回集合個數
//long SortedSetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey first, RedisKey second, Aggregate aggregate = Aggregate.Sum, CommandFlags flags = CommandFlags.None);
db.SortedSetCombineAndStore(SetOperation.Union, "newzsetkey", "zsetkey", "zsetkey1");
//long SortedSetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey[] keys, double[] weights = null, Aggregate aggregate = Aggregate.Sum, CommandFlags flags = CommandFlags.None);
db.SortedSetCombineAndStore(SetOperation.Union, "newzsetkey", new RedisKey[] { "zsetkey", "zsetkey1" });


//2.5.5 other
//scan,可指定位置和偏移
//IEnumerable<SortedSetEntry> SortedSetScan(RedisKey key, RedisValue pattern, int pageSize, CommandFlags flags);
db.SortedSetScan("", "?國", 10, CommandFlags.None);
//IEnumerable<SortedSetEntry> SortedSetScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = 10, long cursor = 0, int pageOffset = 0, CommandFlags flags = CommandFlags.None);
db.SortedSetScan("", "?國", 10, 0, 1, CommandFlags.None);

//排序score加等於
//double SortedSetIncrement(RedisKey key, RedisValue member, double value, CommandFlags flags = CommandFlags.None);
db.SortedSetIncrement("zsetkey1", "阿根廷", 6);
//排序score減等於
//double SortedSetDecrement(RedisKey key, RedisValue member, double value, CommandFlags flags = CommandFlags.None);
db.SortedSetDecrement("zsetkey1", "阿根廷", 5);

//獲取score在這之間元素的個數
//long SortedSetLength(RedisKey key, double min = double.NegativeInfinity, double max = double.PositiveInfinity, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None);
db.SortedSetLength("zsetkey1", 0, 3);
//long SortedSetLengthByValue(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None);
//同一score的元素在此之間的元素個數
db.SortedSetLengthByValue("zsetkey1", 0, 2);
//val值的個數
//long? SortedSetRank(RedisKey key, RedisValue member, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None);
db.SortedSetRank("newzsetkey", "意大利");

    2.6 HyperLogLog

//添加元素到HyperLogLog數據結構
//bool HyperLogLogAdd(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None);
//bool HyperLogLogAdd(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None);
db.HyperLogLogAdd("HyperLogLogKey", "c sharp");
db.HyperLogLogAdd("HyperLogLogKey", new RedisValue[] { "c++", "java", "object-c" });

//返回指定HyperLogLog結構key上元素的近似基數
//long HyperLogLogLength(RedisKey key, CommandFlags flags = CommandFlags.None);
//long HyperLogLogLength(RedisKey[] keys, CommandFlags flags = CommandFlags.None);
Console.WriteLine(db.HyperLogLogLength("HyperLogLogKey"));
db.HyperLogLogLength(new RedisKey[] { "HyperLogLogKey", "HyperLogLogKey1" });

//合並
//void HyperLogLogMerge(RedisKey destination, RedisKey[] sourceKeys, CommandFlags flags = CommandFlags.None);
//void HyperLogLogMerge(RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None);
db.HyperLogLogMerge("newHyperLogLogKey", "HyperLogLogKey", "HyperLogLogKey1");
db.HyperLogLogMerge("newHyperLogLogKey", new RedisKey[] { "HyperLogLogKey", "HyperLogLogKey1" });

    2.7 bit

// set
//bool StringSetBit(RedisKey key, long offset, bool bit, CommandFlags flags = CommandFlags.None);
db.StringSetBit("bitkey", 0, true);
// get
//bool StringGetBit(RedisKey key, long offset, CommandFlags flags = CommandFlags.None);
Console.WriteLine(db.StringGetBit("bitkey", 0));

//other
//long StringBitCount(RedisKey key, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None);
Console.WriteLine(db.StringBitCount("bitkey",0,1));
//long StringBitPosition(RedisKey key, bool bit, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None);
Console.WriteLine(db.StringBitPosition("bitkey",false, 0, 1));

//多key之間取與或非運算,存入新的key:destination
//long StringBitOperation(Bitwise operation, RedisKey destination, RedisKey[] keys, CommandFlags flags = CommandFlags.None);
db.StringBitOperation(Bitwise.And, "newbitkey", new RedisKey[] { "bitkey1", "bitkey2" });
//long StringBitOperation(Bitwise operation, RedisKey destination, RedisKey first, RedisKey second = default(RedisKey), CommandFlags flags = CommandFlags.None);
db.StringBitOperation(Bitwise.And, "newbitkey", "bitkey1", "bitkey2");

    2.8 key

//del 刪除單個及多個key
//bool KeyDelete(RedisKey key, CommandFlags flags = CommandFlags.None);
db.KeyDelete("key1");
//long KeyDelete(RedisKey[] keys, CommandFlags flags = CommandFlags.None);
db.KeyDelete(new RedisKey[] {"key1","key2" });

//是否存在
//bool KeyExists(RedisKey key, CommandFlags flags = CommandFlags.None);

//是否過期
//bool KeyExpire(RedisKey key, TimeSpan? expiry, CommandFlags flags = CommandFlags.None);

//bool KeyExpire(RedisKey key, DateTime? expiry, CommandFlags flags = CommandFlags.None);

//序列號key 參考:http://redis.io/commands/dump
//byte[] KeyDump(RedisKey key, CommandFlags flags = CommandFlags.None);

//key的轉移,保證源庫上的key刪除,目標庫的key增加 參考:http://redis.io/commands/MIGRATE
//void KeyMigrate(RedisKey key, EndPoint toServer, int toDatabase = 0, int timeoutMilliseconds = 0, MigrateOptions migrateOptions = MigrateOptions.None, CommandFlags flags = CommandFlags.None);
//key轉移到目標庫 http://redis.io/commands/move
//bool KeyMove(RedisKey key, int database, CommandFlags flags = CommandFlags.None);

//刪除現有的超時key http://redis.io/commands/persist
//bool KeyPersist(RedisKey key, CommandFlags flags = CommandFlags.None);

//隨機返回一個key http://redis.io/commands/randomkey
//RedisKey KeyRandom(CommandFlags flags = CommandFlags.None);

//重命名key http://redis.io/commands/renamenx
//bool KeyRename(RedisKey key, RedisKey newKey, When when = When.Always, CommandFlags flags = CommandFlags.None);

//重新序列化存儲key http://redis.io/commands/restore
//void KeyRestore(RedisKey key, byte[] value, TimeSpan? expiry = default(TimeSpan?), CommandFlags flags = CommandFlags.None);
//返回key還有多久到期 http://redis.io/commands/ttl
//TimeSpan? KeyTimeToLive(RedisKey key, CommandFlags flags = CommandFlags.None);

//key對應數據的類型 http://redis.io/commands/type
//RedisType KeyType(RedisKey key, CommandFlags flags = CommandFlags.None);

    2.9 script

//script 核心還在redis腳本的編寫 http://redis.io/commands/eval
//RedisResult ScriptEvaluate(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None);
db.ScriptEvaluate(LuaScript.Prepare("redis.call('set', @key, @value)"), new { key = "mykey", value = "myvalue" });
//RedisResult ScriptEvaluate(LuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None);
db.ScriptEvaluate(LuaScript.Prepare("redis.call('set', @key, @value)"), new { key = "mykey", value = "myvalue" });
//RedisResult ScriptEvaluate(byte[] hash, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None);
byte[] resbytes = new SHA1CryptoServiceProvider().ComputeHash(Encoding.Default.GetBytes("..."));
RedisResult res = db.ScriptEvaluate(resbytes, new RedisKey[] { "key1", "key2" }, new RedisValue[] { "first", "second" });
Console.WriteLine(res);
//RedisResult ScriptEvaluate(string script, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None);
db.ScriptEvaluate("return {key[1],key[2],argv[1],argv[2]}",
        new RedisKey[] { "key1", "key2" }, new RedisValue[] { "first", "second" });
Console.ReadKey();

    2.10 transaction

//db.StringSet("trankey", "yes");
//2.9.1 一個簡單的列子就足夠了:如果trankey的值為yes,則改為no
//開啟一個事物
ITransaction tran = db.CreateTransaction();
//為事物增加一個執行的前提條件,也可以不添加
ConditionResult cr = tran.AddCondition(Condition.StringEqual("trankey", "yes"));
//注意:此處cr.WasSatisfied仍為默認值false,待執行Execute()之后才會返回真實結果,如果為true,則exec將會執行,否則rollback
//因為異步等待狀態,所以無需判斷
tran.StringSetAsync("trankey", "no");
//commit/rollback
bool committed = tran.Execute();
Console.WriteLine(cr.WasSatisfied);
Console.WriteLine(committed);

  2.11 Task

//異步都會有Async,所以前面都沒有列出來
Task<bool> t = db.StringSetAsync("asyncstringkey", "none");
//可以看到是false,因為異步線程還沒有執行操作
Console.WriteLine(t.IsCompleted);
Task<bool> t1 = db.StringSetAsync("asyncstringkey1", "none1");
t1.Wait();
//等待執行完成,返回true
Console.WriteLine(t.IsCompleted);

    2.12 lock

//lock主要是對一些多線程操作的處理,lock三種狀態
//  鍵(在數據庫中的鎖的唯一名稱)
//  值(一個調用者指示誰“擁有”該鎖,並且檢查釋放和延長鎖被正確完成)
//  key的持續時間
//bool LockExtend(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags = CommandFlags.None);
//RedisValue LockQuery(RedisKey key, CommandFlags flags = CommandFlags.None);
//bool LockRelease(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None);
//bool LockTake(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags = CommandFlags.None);
string val = DateTime.Now.ToString();
if (db.LockTake("mykey", val, TimeSpan.FromSeconds(10)))
{
    try
    {
        //其他線程就不可以take了,等待當前線程操作完release之后。
    }
    finally
    {
        db.LockRelease("mykey", val);
    }
}

歡迎轉載,來爬我啊:http://www.cnblogs.com/NotAnEmpty/p/5441127.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM