Redis-技術專題-Jedis實戰入門

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Redis是一個開源,高級的鍵值存儲和一個適用的解決方案,用於構建高性能,可擴展的Web應用程序。本文將概要介紹Redis的特性和語法,並以實例代碼的形式介紹如何通過Jedis在java語言環境下控制Redis,幫助各位讀者快速入門。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"NoSQL概述"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis是NoSQL數據庫的代表之一,那什麼是NoSQL?"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"NoSQL = not only SQL,即非關係型數據庫。"}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Why NoSQL?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"和傳統的關係型數據庫相比,NoSQL具有以下的優勢:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"High Performance:高併發讀寫;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"Huge Storage: 海量數據的高效存儲和訪問;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"High Scalability & High Availability:高可擴展和高可用性"}]}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"NoSQL的分類:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"Key-Value,如Redis,快速查詢,但是數據存儲缺少結構化;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"列存儲,如HBase, 擴展性強,查找速度快,但是功能侷限;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"文檔數據庫,如MongoDB,數據格式靈活,查詢性能不高,缺少統一的查詢語法;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"圖形數據庫,如InfoGrid,基於圖的算法,但是不容易做分佈式的查詢;"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Redis概述"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Redis是一個開源,高性能的鍵值對數據庫, 其優點包括:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"異常快"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":" :Redis非常快,每秒可執行大約110000次的設置(SET)操作,每秒大約可執行81000次的讀取/獲取(GET)操作。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"支持豐富的數據類型"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":" :Redis支持開發人員常用的大多數數據類型,例如"},{"type":"text","marks":[{"type":"italic"},{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"列表"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":","},{"type":"text","marks":[{"type":"italic"},{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"集合"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":","},{"type":"text","marks":[{"type":"italic"},{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"排序集"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"和"},{"type":"text","marks":[{"type":"italic"},{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"散列"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"等等。這使得Redis很容易被用來解決各種問題,因爲我們知道哪些問題可以更好使用地哪些數據類型來處理解決。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"操作具有原子性"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":" : 所有Redis操作都是原子操作,這確保如果兩個客戶端併發訪問,Redis服務器能接收更新的值。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"多實用工具"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":" : Redis是一個多實用工具,可用於多種用例,如:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"緩存"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":";"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"任務隊列"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":";網站統計;"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"數據過期處理"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":";應用排行榜;"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"分佈式集羣的Session分離"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":";"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Redis與其他鍵值存儲系統"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"Redis是鍵值數據庫系統的不同進化路線,它的值可以包含更復雜的數據類型,可在這些數據類型上定義原子操作。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"Redis是一個內存數據庫,但在磁盤數據庫上是持久的,因此它代表了一個不同的權衡,在這種情況下,在不能大於存儲器(內存)的數據集的限制下實現非常高的寫和讀速度。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"內存數據庫的另一個優點是,它與磁盤上的相同數據結構相比,複雜數據結構在內存中存儲表示更容易操作。 因此,Redis可以做很少的內部複雜性。"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Redis的安裝和使用"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis的安裝是否簡單,在Ubuntu上安裝Redis,打開終端並鍵入以下命令即可"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"sudo apt-get update \nsudo apt-get install redis-server"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"啓動服務器:"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"redis-server"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"啓動客戶端:"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"redis-cli"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果是Windows環境下,則參照以下文章:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://link.jianshu.com/?t=http%3A%2F%2Fdownload.csdn.net%2Fdownload%2Ffengxinyixiao%2F9860813","title":null},"content":[{"type":"text","text":"http://download.csdn.net/download/fengxinyixiao/9860813"}]},{"type":"link","attrs":{"href":"https://link.jianshu.com/?t=http%3A%2F%2Fblog.csdn.net%2Fjoyhen%2Farticle%2Fdetails%2F47358999","title":null},"content":[{"type":"text","text":"http://blog.csdn.net/joyhen/article/details/47358999"}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Jedis入門"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Jedis是Redis官網首選的Java客戶端開發包."}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d8/d8636d4b9df6615281dce3dcc6dd2062.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Jedis是Redis官網首選的Java客戶端開發包"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其GItHub地址爲:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://link.jianshu.com/?t=https%3A%2F%2Fgithub.com%2Fxetorthio%2Fjedis","title":null},"content":[{"type":"text","text":"https://github.com/xetorthio/jedis"}]}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在Maven中,添加如下依賴即可使用:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"\n redis.clients\n jedis\n 2.9.0\n jar\n compile\n\n"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以下是官網是上給出的示例代碼,連接本地Redis,進行操作."}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" @Test\n public void ConnectionTest(){\n //1. Connecting to Redis server on localhost\n Jedis jedis = new Jedis(\"localhost\");\n System.out.println(\"Connection to server sucessfully\");\n //2. set the data in redis string\n jedis.set(\"username\", \"Roxin\");\n //3. Get the stored data and print it\n System.out.println(\"Stored string in redis:: \"+ jedis.get(\"username\"));\n //4. Close the Redis connection;\n jedis.close();\n }"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其中通過調用"},{"type":"codeinline","content":[{"type":"text","text":"set"}]},{"type":"text","text":"方法來設置鍵值對,通過"},{"type":"codeinline","content":[{"type":"text","text":"get"}]},{"type":"text","text":"方法獲取鍵值對。"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"除此之外,Jedis還提供連接池的方式控制連接"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" @Test\n public void ConnectionPoolTest(){\n //連接池設定\n JedisPoolConfig config = new JedisPoolConfig();\n //設定最大連接數\n config.setMaxTotal(30);\n //設置最大空閒連接數\n config.setMaxIdle(10);\n //創建連接池\n JedisPool jedisPool = new JedisPool(config, \"127.0.0.1\");\n //獲得服務資源\n Jedis jedis = jedisPool.getResource();\n jedis.select(1);\n jedis.set(\"username\", \"Roxin By Jedis Pool\");\n System.out.println(jedis.get(\"username\"));\n jedis.close();\n jedisPool.close();\n }\n"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Redis的數據類型"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis中的數據類型有:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"字符串(String)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"列表(list)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"有序集合(sorted set)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"散列(hash)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"集合(set)"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"無論哪種數據類型都需要爲其設定鍵值Key,設置Key的注意點:"}]},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":1,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"不要太長(<1024字節);"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":2,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"不要太短,有可讀性;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":3,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"統一命名規範;"}]}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"String"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Redis中的字符串是一個字節序列。Redis中的字符串是二進制安全的,這意味着它們的長度不由任何特殊的終止字符決定。因此,可以在一個字符串中存儲高達512兆字節的任何內容。"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"除了上面提到的set/get方法,還有其他命令如下表:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a9/a93f1bef74bfdd7f3d585c8228b84119.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Hash"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 相當於Map,在Redis中,每個哈希(散列)可以存儲多達4億個鍵-值對。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Jedis示例代碼如下"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" @Test\n public void HashTest(){\n Jedis jedis = jedisPool.getResource();\n String hashKey = \"hashKey\";\n //hset設置一個鍵值對\n jedis.hset(hashKey,\"user\",\"Roxin\");\n HashMap map = new HashMap<>();\n for (int i = 0; i < 10; i++) {\n map.put(\"field\"+i,\"value\"+i);\n }\n //設置多個鍵值對\n jedis.hmset(hashKey,map);\n //獲得鍵值對的個數\n Long hlen = jedis.hlen(hashKey);\n System.out.println(\"Hash Size in redis:: \"+hlen);\n assert hlen==11;\n //得到全部鍵值對\n List user = jedis.hmget(hashKey, \"user\");\n System.out.println(\"Stored string in redis:: \"+ user);\n assert user.get(0).equals(\"Roxin\");\n //刪除鍵值\n jedis.del(hashKey);\n jedis.close();\n }\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis關於Hash類型的常見命令如下表:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/42/42e0f41957db0f35571891d10bcface1.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"list"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Redis列表只是字符串列表,按插入順序排序。可以在列表的頭部或尾部添加Redis列表中的元素。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"列表的最大長度爲"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"2^32 - 1個元素(即4294967295,每個列表可存儲超過40億個元素)"},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Jedis中示例代碼如下"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" @Test\n public void ListTest(){\n Jedis jedis = jedisPool.getResource();\n String listKey = \"LISTKEY\";\n for (int i = 0; i < 10; i++) {\n //從頭插入一個元素\n jedis.lpush(listKey,\"L-value\");\n }\n List list = jedis.lrange(listKey, 0, -1);//從第一個到最後一個,負數代表倒數第幾個\n assert list.size() == 10;\n assert \"L-value\".equals(jedis.rpop(listKey));//從尾部取出一個元素\n assert 9==jedis.llen(listKey);\n jedis.rpush(listKey,\"R-valure\");//從尾部加入一個元素\n jedis.lrem(listKey,2,\"L-value\");//刪除從左數2兩個\"L-value\"元素\n jedis.lrem(listKey,0,\"L-value\"); //0表示刪除全部\"L-value\"元素\n assert \"R-valure\".equals(jedis.lpop(listKey));//從頭部加入一個元素\n jedis.del(listKey);\n jedis.close();\n }"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis中關於list的命令如下表:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/e0/e05514f606453728165605da66d95ae8.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"需要特別說明下:"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"codeinline","content":[{"type":"text","text":"rpoplpush source destination"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":" 刪除列表中的最後一個元素,將其附加到另一個列表並返回,在消息隊列中,可以用於消息備份:當消息被髮布後,一個消息從主消息隊列中被取出,被放入到緩存隊列中,當確認發生成功之後,再將其徹底刪除,如果發送不成功,就恢復該消息。"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/df/df48338166a31ec201e34e58656f0d14.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Set"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Redis集合是唯一字符串的無序集合。 唯一值表示集合中不允許鍵中有重複的數據。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 在Redis中設置添加,刪除和測試成員的存在(恆定時間O(1),而不考慮集合中包含的元素數量)。列表的最大長度爲2^32 - 1個元素(即4294967295,每組集合超過40億個元素)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"存儲Set的使用場景:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"跟蹤唯一性數據"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用於維護數據對象之間的關聯關係;"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Jedis的代碼示例:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" @Test\n public void SetTest(){\n Jedis jedis = jedisPool.getResource();\n String setKey1 = \"SETKEY-1\";\n for (int i = 0; i < 10; i++) {\n //添加一個元素\n jedis.sadd(setKey1,\"value-\"+i);\n }\n assert 10 == jedis.scard(setKey1); //獲得元素個數\n jedis.sadd(setKey1,\"value-1\");//添加重複的元素將失效\n assert 10 == jedis.scard(setKey1);\n String s= jedis.srandmember(setKey1);//隨機獲取一個元素\n assert jedis.sismember(setKey1,s);//是否爲集合成員\n String setKey2 = \"SETKEY-2\";\n for (int i = 1; i < 11; i++) {\n jedis.sadd(setKey2,\"value-\"+i);\n }\n assert jedis.sdiff(setKey1,setKey2).size() == 1;//補集\n assert jedis.sinter(setKey1,setKey2).size() == 9;//交集\n assert jedis.sunion(setKey1,setKey2).size() == 11;//並集\n jedis.del(setKey1,setKey2);\n jedis.close();\n }\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis中關於Set的命令如下表:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a8/a8c34249ac27b28a31cb8d254726598b.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Sorted-Set"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Redis可排序集合類似於Redis集合,是不重複的字符集合。 不同之處在於,排序集合的每個成員都與分數相關聯,這個分數用於按最小分數到最大分數來排序的排序集合。雖然成員是唯一的,但分數值可以重複。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Sorted-Set的使用場景:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"大型在線遊戲的積分排名;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"構建索引數據;"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Jedis中的示例:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" @Test\n public void SortedSetTest(){\n Jedis jedis = jedisPool.getResource();\n String sortedSetKey = \"SORTEDSETKEY\";\n for (int i = 0; i < 10; i++) {\n //添加一個元素\n jedis.zadd(sortedSetKey,i*10,\"v-\"+i);\n }\n assert 10 == jedis.zcard(sortedSetKey);//獲得集合中元素個數\n assert 20 == (jedis.zscore(sortedSetKey,\"v-2\"));//獲得集合中元素對應的分數\n Set set = jedis.zrange(sortedSetKey, 0, -2);//從第一個到倒數第二個\n assert 9 == set.size() ;\n assert !set.contains(\"v-9\");\n jedis.zincrby(sortedSetKey,20,\"v-1\");//讓元素的分數增長20\n assert 30 == jedis.zscore(sortedSetKey,\"v-1\");\n assert 3 == jedis.zcount(sortedSetKey,20,30);//獲得分數段中元素個數\n jedis.del(sortedSetKey);\n jedis.close();\n }"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Keys的通用操作"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Jedis中關於鍵值操作的實例:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" @Test\n public void KeyTest(){\n Jedis jedis = jedisPool.getResource();\n String key = \"TESTKEY-1\";\n String key2 = \"TESTKEY-2\";\n jedis.set(key2,\"\");//設置鍵值\n jedis.rename(key2,key);//鍵值重命名\n System.out.println(\"Key Type:\"+jedis.type(key));//鍵值的類型\n assert jedis.exists(key);//鍵值是否存在\n jedis.expire(key,1);//設置鍵值過期時間\n assert 1 == jedis.ttl(key);//查看鍵值過期時間\n try {\n Thread.sleep(2000);//睡眠2s\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n assert !jedis.exists(key);//鍵值已過期,不存在\n }\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis中關於鍵值的其他命令:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d1/d178f71e3dd7aaa93fc37d0cc053f492.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"KEYS pattern"}]},{"type":"text","text":" 查找與指定模式匹配的所有鍵:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"keys * 查看所有的key;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"keys xx? 模糊匹配key;"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Redis的特性"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"多數據"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"提供16個數據庫(0-15),默認爲0號數據庫,可是通過"},{"type":"codeinline","content":[{"type":"text","text":"select index"}]},{"type":"text","text":"選擇。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"事務"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"和關係型數據庫一樣,Redis也提供事務性操作:"}]},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"DISCARD 丟棄在MULTI之後發出的所有命令(放棄事務,回滾)"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"EXEC 執行MULTI後發出的所有命令(提交事務)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"MULTI 標記事務塊的開始(開始事務)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"UNWATCH 取消 WATCH 命令對所有 key 的監視。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":5,"align":null,"origin":null},"content":[{"type":"text","text":"WATCH key [key …] 監視給定的鍵以確定MULTI / EXEC塊的執行"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis中示例代碼如下:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" @Test\n public void TransactionTest(){\n //獲得服務資源\n Jedis jedis = jedisPool.getResource();\n jedis.select(1);\n Transaction transaction = jedis.multi();//開啓事務\n transaction.set(\"username\", \"Roxin in transaction1\");\n System.out.println(transaction.get(\"username\"));\n transaction.exec();//提交事務\n System.out.println(jedis.get(\"username\"));\n transaction = jedis.multi();//開啓事務\n transaction.set(\"username\", \"Roxin in transaction2\");\n System.out.println(transaction.get(\"username\"));\n transaction.discard();//撤銷事務\n System.out.println(jedis.get(\"username\"));\n jedis.close();\n }\n"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Redis持久化"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis是一個內存數據庫,但在磁盤數據庫上是持久化的,持久化的方式分爲兩種:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"RDB:默認方式,定時將內存數據集快照寫入磁盤;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"AOF:以日誌的方式,記錄所有操作;"}]}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"RDB"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"優勢"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"數據只存在一個文件中,便於數據歸檔和整理;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"多線程啓動,性能好;"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"劣勢"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果在兩次快照寫操作之間出現問題,將無法回覆期間的數據;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"多線程啓動的時候,可能會有停頓;"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"配置文件爲Redis按照目錄下的 redis.conf:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/07/072d7031ea58a258c192943923129609.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"redis.conf 保存頻率的設施"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這是配置文件設置內存快照寫入磁盤的條件"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"# In the example below the behaviour will be to save:\n# after 900 sec (15 min) if at least 1 key changed\n# after 300 sec (5 min) if at least 10 keys changed\n# after 60 sec if at least 10000 keys changed\nsave 900 1 \nsave 300 10\nsave 60 10000\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"數據文件被定義爲"},{"type":"codeinline","content":[{"type":"text","text":"dump.rdb"}]},{"type":"text","text":",保存路徑爲Redis的按照路徑。"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"# The filename where to dump the DB\ndbfilename dump.rdb\n\n# The working directory.\n#\n# The DB will be written inside this directory, with the filename specified\n# above using the 'dbfilename' configuration directive.\n#\n# The Append Only File will also be created inside this directory.\n#\n# Note that you must specify a directory here, not a file name.\ndir ./\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f1/f14c938786c276580504e348a944de73.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis數據文件,只有一個數據文件"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"AOF"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"優勢:"}]},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"更高的數據安全性,有三種數據同步策略:"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"日誌是追加(append)模式,即使有宕機,也不會用問題。 如果是數據寫入一半出現問題,可以使用redis-check-aof,恢復數據一致;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"日誌自動重寫,以防止日誌過大;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"日誌格式清楚明瞭,可用於數據重建;"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"劣勢:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"文件要更大;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"運行效率更低;"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"配置文件中關於AOF的配置:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d6/d624d1b0b8adc62aaeaa52671526e096.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"關於AOF的配置"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"默認不使用;"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"日誌文件爲 "},{"type":"codeinline","content":[{"type":"text","text":"appendonly.aof"}]}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"# The name of the append only file (default: \"appendonly.aof\")\nappendfilename \"appendonly.aof\"\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上面提高的三種同步策略;"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"# no: don't fsync, just let the OS flush the data when it wants. Faster.\n# always: fsync after every write to the append only log. Slow, Safest.\n# everysec: fsync only one time every second. Compromise.\n#\n# The default is \"everysec\",If unsure, use \"everysec\".\n\n# appendfsync always\nappendfsync everysec\n# appendfsync no"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章