Redis 小白指南(一)- 簡介、安裝、GUI 和 C# 驅動介紹 目錄 簡介 安裝 入門指令 GUI 工具 C# 驅動介紹 簡介 ANSI C 編寫,開源,基於記憶體,可持久化,一個鍵值對的資料庫,用法簡單。 支持的類型:字元串、散列、列表、集合和有序集合。 因為 Redis 預設將所有數據都存儲 ...
Redis 小白指南(一)- 簡介、安裝、GUI 和 C# 驅動介紹
目錄
- 簡介
- 安裝
- 入門指令
- GUI 工具
- C# 驅動介紹
簡介
ANSI C 編寫,開源,基於記憶體,可持久化,一個鍵值對的資料庫,用法簡單。
支持的類型:字元串、散列、列表、集合和有序集合。
因為 Redis 預設將所有數據都存儲到記憶體中,並且記憶體的讀寫速度遠遠高於硬碟,因此,比其他基於硬碟存儲的資料庫在性能上體現的優勢非常明顯。不過這樣也引發了一個數據安全性的問題,程式異常或退出後數據會出現丟失的情形,現在新的版本已經提供了數據持久化(RDB + AOF)的支持,即可以將記憶體中的數據非同步寫入到硬碟上,同時不會影響其它功能的運行。
redis 可以為每個鍵設置生存時間,到期自動刪除,也就是說可以作為緩存系統(這也是企業主要的運用場景)進行使用。
相對於 Memcached,簡單的說:Redis 單線程模型,Memcached 支持多線程,但 Redis 支持的功能和數據類型更多,更簡單易用,並且 redis 的性能在絕大部分場合下都不會成為系統瓶頸,不過在多核伺服器上使用的情況下,理論上 Memcached 比 redis 性能更高。所以,在新項目中,建議使用 redis 代替 Memcached。
Redis 還可以限定數據占用的最大記憶體空間,在數據達到空間限制後按一定規則自動淘汰不需要的鍵;也支持構建高性能的隊列(不過很多企業會選擇第三方的 MQ,如:RabbitMQ)。
安裝
它的約定次版本號(即第一個小數點後的數字)為偶數的版本是穩定版(如 v2.8,v3.0)。
為了減少學習成本,我們直接使用 windows 版本的就可以,想學習 Linux 部署的,先搜搜別人的文章吧。
redis-windows-3.0:下載地址
文件簡單說明:
入門指令
1.啟動:
$ redis-server $ redis-server --port 6380 //自定義埠
2.停止:
$ redis-cli SHUTDOWN
3.PING 命令:
測試與 redis 的連接是否正常,正常返回 PONG
$ redis-cli PING
GUI 工具
Redis Client:一個基於Java SWT 和 Jedis 編寫的 redis 客戶端 GUI 工具。可從 https://github.com/caoxinyu/RedisClient 下載。
從圖可知,redis 包含了 16 個資料庫。上面的每個資料庫預設從 0 開始的遞增數字命名。
因為該程式打包後的壓縮包 >10 M,無法上傳到 cnblogs,如有需要的童鞋請加群在群文件中下載壓縮包。
C# 驅動
之前在 《使用 StackExchange.Redis 封裝屬於自己的 RedisHelper》 曾經發佈了一篇使用 StackExchange.Redis 進行了簡單封裝的 RedisHelper,你可以選擇查看之前的文章,從中借鑒一些思想或者給出一些建議。
這裡是更新後的 Helper 代碼(直接展開即可),代碼的後續更新在 GitHub 上。
1 #region 2 3 using System; 4 using System.Collections.Generic; 5 using System.Configuration; 6 using System.IO; 7 using System.Linq; 8 using System.Runtime.Serialization.Formatters.Binary; 9 using System.Threading.Tasks; 10 using StackExchange.Redis; 11 12 #endregion 13 14 namespace Wen.Helpers.Common.Redis 15 { 16 /// <summary> 17 /// Redis 助手 18 /// </summary> 19 public class RedisHelper 20 { 21 /// <summary> 22 /// 獲取 Redis 連接對象 23 /// </summary> 24 /// <returns></returns> 25 public IConnectionMultiplexer GetConnectionRedisMultiplexer() 26 { 27 if (_connMultiplexer == null || !_connMultiplexer.IsConnected) 28 lock (Locker) 29 { 30 if (_connMultiplexer == null || !_connMultiplexer.IsConnected) 31 _connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString); 32 } 33 34 return _connMultiplexer; 35 } 36 37 #region 其它 38 39 public ITransaction GetTransaction() 40 { 41 return _db.CreateTransaction(); 42 } 43 44 #endregion 其它 45 46 #region private field 47 48 /// <summary> 49 /// 連接字元串 50 /// </summary> 51 private static readonly string ConnectionString; 52 53 /// <summary> 54 /// redis 連接對象 55 /// </summary> 56 private static IConnectionMultiplexer _connMultiplexer; 57 58 /// <summary> 59 /// 預設的 Key 值(用來當作 RedisKey 的首碼) 60 /// </summary> 61 private static readonly string DefaultKey; 62 63 /// <summary> 64 /// 鎖 65 /// </summary> 66 private static readonly object Locker = new object(); 67 68 /// <summary> 69 /// 資料庫 70 /// </summary> 71 private readonly IDatabase _db; 72 73 #endregion private field 74 75 #region 構造函數 76 77 static RedisHelper() 78 { 79 ConnectionString = ConfigurationManager.ConnectionStrings["RedisConnectionString"].ConnectionString; 80 _connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString); 81 DefaultKey = ConfigurationManager.AppSettings["Redis.DefaultKey"]; 82 AddRegisterEvent(); 83 } 84 85 public RedisHelper(int db = 0) 86 { 87 _db = _connMultiplexer.GetDatabase(db); 88 } 89 90 #endregion 構造函數 91 92 #region String 操作 93 94 /// <summary> 95 /// 設置 key 並保存字元串(如果 key 已存在,則覆蓋值) 96 /// </summary> 97 /// <param name="key"></param> 98 /// <param name="value"></param> 99 /// <param name="expiry"></param> 100 /// <returns></returns> 101 public bool StringSet(string key, string value, TimeSpan? expiry = null) 102 { 103 key = AddKeyPrefix(key); 104 return _db.StringSet(key, value, expiry); 105 } 106 107 /// <summary> 108 /// 保存多個 Key-value 109 /// </summary> 110 /// <param name="keyValuePairs"></param> 111 /// <returns></returns> 112 public bool StringSet(IEnumerable<KeyValuePair<string, string>> keyValuePairs) 113 { 114 var pairs = keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value)); 115 return _db.StringSet(pairs.ToArray()); 116 } 117 118 /// <summary> 119 /// 獲取字元串 120 /// </summary> 121 /// <param name="redisKey"></param> 122 /// <param name="expiry"></param> 123 /// <returns></returns> 124 public string StringGet(string redisKey) 125 { 126 redisKey = AddKeyPrefix(redisKey); 127 return _db.StringGet(redisKey); 128 } 129 130 /// <summary> 131 /// 存儲一個對象(該對象會被序列化保存) 132 /// </summary> 133 /// <param name="key"></param> 134 /// <param name="value"></param> 135 /// <param name="expiry"></param> 136 /// <returns></returns> 137 public bool StringSet<T>(string key, T value, TimeSpan? expiry = null) 138 { 139 key = AddKeyPrefix(key); 140 var json = Serialize(value); 141 142 return _db.StringSet(key, json, expiry); 143 } 144 145 /// <summary> 146 /// 獲取一個對象(會進行反序列化) 147 /// </summary> 148 /// <param name="key"></param> 149 /// <param name="expiry"></param> 150 /// <returns></returns> 151 public T StringGet<T>(string key, TimeSpan? expiry = null) 152 { 153 key = AddKeyPrefix(key); 154 return Deserialize<T>(_db.StringGet(key)); 155 } 156 157 /// <summary> 158 /// 在指定 key 處實現增量的遞增,如果該鍵不存在,則在執行前將其設置為 0 159 /// </summary> 160 /// <param name="key"></param> 161 /// <param name="value"></param> 162 /// <returns></returns> 163 public double StringIncrement(string key, double value = 1) 164 { 165 key = AddKeyPrefix(key); 166 return _db.StringIncrement(key, value); 167 } 168 169 /// <summary> 170 /// 在指定 key 處實現增量的遞減,如果該鍵不存在,則在執行前將其設置為 0 171 /// </summary> 172 /// <param name="key"></param> 173 /// <param name="value"></param> 174 /// <returns></returns> 175 public double StringDecrement(string key, double value = 1) 176 { 177 key = AddKeyPrefix(key); 178 return _db.StringDecrement(key, value); 179 } 180 181 #region async 182 183 /// <summary> 184 /// 保存一個字元串值 185 /// </summary> 186 /// <param name="key"></param> 187 /// <param name="value"></param> 188 /// <param name="expiry"></param> 189 /// <returns></returns> 190 public async Task<bool> StringSetAsync(string key, string value, TimeSpan? expiry = null) 191 { 192 key = AddKeyPrefix(key); 193 return await _db.StringSetAsync(key, value, expiry); 194 } 195 196 /// <summary> 197 /// 保存一組字元串值 198 /// </summary> 199 /// <param name="keyValuePairs"></param> 200 /// <returns></returns> 201 public async Task<bool> StringSetAsync(IEnumerable<KeyValuePair<string, string>> keyValuePairs) 202 { 203 var pairs = keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value)); 204 return await _db.StringSetAsync(pairs.ToArray()); 205 } 206 207 /// <summary> 208 /// 獲取單個值 209 /// </summary> 210 /// <param name="key"></param> 211 /// <param name="value"></param> 212 /// <param name="expiry"></param> 213 /// <returns></returns> 214 public async Task<string> StringGetAsync(string key, string value, TimeSpan? expiry = null) 215 { 216 key = AddKeyPrefix(key); 217 return await _db.StringGetAsync(key); 218 } 219 220 /// <summary> 221 /// 存儲一個對象(該對象會被序列化保存) 222 /// </summary> 223 /// <param name="key"></param> 224 /// <param name="value"></param> 225 /// <param name="expiry"></param> 226 /// <returns></returns> 227 public async Task<bool> StringSetAsync<T>(string key, T value, TimeSpan? expiry = null) 228 { 229 key = AddKeyPrefix(key); 230 var json = Serialize(value); 231 return await _db.StringSetAsync(key, json, expiry); 232 } 233 234 /// <summary> 235 /// 獲取一個對象(會進行反序列化) 236 /// </summary> 237 /// <param name="key"></param> 238 /// <param name="expiry"></param> 239 /// <returns></returns> 240 public async Task<T> StringGetAsync<T>(string key, TimeSpan? expiry = null) 241 { 242 key = AddKeyPrefix(key); 243 return Deserialize<T>(await _db.StringGetAsync(key)); 244 } 245 246 /// <summary> 247 /// 在指定 key 處實現增量的遞增,如果該鍵不存在,則在執行前將其設置為 0 248 /// </summary> 249 /// <param name="key"></param> 250 /// <param name="value"></param> 251 /// <returns></returns> 252 public async Task<double> StringIncrementAsync(string key, double value = 1) 253 { 254 key = AddKeyPrefix(key); 255 return await _db.StringIncrementAsync(key, value); 256 } 257 258 /// <summary> 259 /// 在指定 key 處實現增量的遞減,如果該鍵不存在,則在執行前將其設置為 0 260 /// </summary> 261 /// <param name="key"></param> 262 /// <param name="value"></param> 263 /// <returns></returns> 264 public async Task<double> StringDecrementAsync(string key, double value = 1) 265 { 266 key = AddKeyPrefix(key); 267 return await _db.StringDecrementAsync(key, value); 268 } 269 270 #endregion async 271 272 #endregion String 操作 273 274 #region Hash 操作 275 276 /// <summary> 277 /// 判斷該欄位是否存在 hash 中 278 /// </summary> 279 /// <param name="key"></param> 280 /// <param name="hashField"></param> 281 /// <returns></returns> 282 public bool HashExists(string key, string hashField) 283 { 284 key = AddKeyPrefix(key); 285 return _db.HashExists(key, hashField); 286 } 287 288 /// <summary> 289 /// 從 hash 中移除指定欄位 290 /// </summary> 291 /// <param name="key"></param> 292 /// <param name="hashField"></param> 293 /// <returns></returns> 294 public bool HashDelete(string key, string hashField) 295 { 296 key = AddKeyPrefix(key); 297 return _db.HashDelete(key, hashField); 298 } 299 300 /// <summary> 301 /// 從 hash 中移除指定欄位 302 /// </summary> 303 /// <param name="key"></param> 304 /// <param name="hashFields"></param> 305 /// <returns></returns> 306 public long HashDelete(string key, IEnumerable<string> hashFields) 307 { 308 key = AddKeyPrefix(key); 309 var fields = hashFields.Select(x => (RedisValue) x); 310 311 return _db.HashDelete(key, fields.ToArray()); 312 } 313 314 /// <summary> 315 /// 在 hash 設定值 316 /// </summary> 317 /// <param name="key"></param> 318 /// <param name="hashField"></param> 319 /// <param name="value"></param> 320 /// <returns></returns> 321 public bool HashSet(string key, string hashField, string value) 322 { 323 key = AddKeyPrefix(key); 324 return _db.HashSet(key, hashField, value); 325 } 326 327 /// <summary> 328 /// 在 hash 中設定值 329 /// </summary> 330 /// <param name="key"></param> 331 /// <param name="hashFields"></param> 332 public void HashSet(string key, IEnumerable<KeyValuePair<string, string>> hashFields) 333 { 334 key = AddKeyPrefix(key); 335 var entries = hashFields.Select(x => new HashEntry(x.Key, x.Value)); 336 337 _db.HashSet(key, entries.ToArray()); 338 } 339 340 /// <summary> 341 /// 在 hash 中獲取值 342 /// </summary> 343 /// <param name="key"></param> 344 /// <param name="hashField"></param> 345 /// <returns></returns> 346 public string HashGet(string key, string hashField) 347 { 348 key = AddKeyPrefix(key); 349 return _db.HashGet(key, hashField); 350 } 351 352 /// <summary> 353 /// 在 hash 中獲取值 354 /// </summary> 355 /// <param name="key"></param> 356 /// <param name="hashFields"></param> 357 /// <returns></returns> 358 public IEnumerable<string> HashGet(string key, IEnumerable<string> hashFields) 359 { 360 key = AddKeyPrefix(key); 361 var fields = hashFields.Select(x => (RedisValue) x); 362 363 return ConvertStrings(_db.HashGet(key, fields.ToArray())); 364 } 365 366 /// <summary> 367 /// 從 hash 返回所有的欄位值 368 /// </summary> 369 /// <param name="key"></param> 370 /// <returns></returns> 371 public IEnumerable<string> HashKeys(string key) 372 { 373 key = AddKeyPrefix(key); 374 return ConvertStrings(_db.HashKeys(key)); 375 } 376 377 /// <summary> 378 /// 返回 hash 中的所有值 379 /// </summary> 380 /// <param name="key"></param> 381 /// <returns></returns> 382 public IEnumerable<string> HashValues(string key) 383 { 384 key = AddKeyPrefix(key); 385 return ConvertStrings(_db.HashValues(key)); 386 } 387 388 /// <summary> 389 /// 在 hash 設定值(序列化) 390 /// </summary> 391 /// <param name="key"></param> 392 /// <param name="hashField"></param> 393 /// <param name="redisValue"></param> 394 /// <returns></returns> 395 public bool HashSet<T>(string key, string hashField, T redisValue) 396 { 397 key = AddKeyPrefix(key); 398 var json = Serialize(redisValue); 399 400 return _db.HashSet(key, hashField, json); 401 } 402 403 /// <summary> 404 /// 在 hash 中獲取值(反序列化) 405 /// </summary> 406 /// <param name="key"></param> 407 /// <param name="hashField"></param> 408 /// <returns></returns> 409 public T HashGet<T>(string key, string hashField) 410 { 411 key = AddKeyPrefix(key); 412