Redis用戶端開發包:Jedis學習-進階應用程式

來源:互聯網
上載者:User

標籤:

事務

Jedis中事務的寫法是將redis操作寫在事物代碼塊中,如下所示,multi與exec之間為具體的事務。

jedis.watch (key1, key2, ...);Transaction t = jedis.multi();t.set("foo", "bar");t.exec();

另外,在事務內部,是不能通過Jedis對象去擷取值的,不過可以通過Transaction對象去擷取,如下寫法:

package cn.edu.hdu.jedisdemo;import java.util.Set;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.JedisPoolConfig;import redis.clients.jedis.Response;import redis.clients.jedis.Transaction;public class App {    public static void main(String[] args) {        JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost");        // / Jedis implements Closable. Hence, the jedis instance will be        // auto-closed after the last statement.        try (Jedis jedis = pool.getResource()) {            // / ... do stuff here ... for example            Transaction t = jedis.multi();            t.set("fool", "bar");            //jedis.get("fool");//報錯,Cannot use Jedis when in Multi. Please use Transation or reset jedis state.            Response<String> result1 = t.get("fool");            t.zadd("foo", 1, "barowitch");            t.zadd("foo", 0, "barinsky");            t.zadd("foo", 0, "barikoviev");            Response<Set<String>> sose = t.zrange("foo", 0, -1);             t.exec(); // dont forget it            String foolbar = result1.get(); // use Response.get() to retrieve things from a Response            int soseSize = sose.get().size(); // on sose.get() you can directly call Set methods!            // List<Object> allResults = t.exec(); // you could still get all            // results at once, as before            System.out.println(foolbar);            System.out.println(soseSize);        }        // / ... when closing your application:        pool.close();    }}

注意:Response對象的get方法要在事務exec方法執行之後調用,在t.exec()方法執行之前,Response對象是不包含結果的

管道

有時候,我們需要發送多個命令,一個高效的方法是使用管道;

通過管道可以一次性發送多條命令並在執行完後一次性將結果返回,當一組命令中每條命令都不依賴之前命令的執行結果時就可以將這組命令一起通過管道發出;

管道可以減少用戶端與redis的通訊次數,提供效能。

如下樣本:

Pipeline p = jedis.pipelined();p.set("fool", "bar"); p.zadd("foo", 1, "barowitch");  p.zadd("foo", 0, "barinsky"); p.zadd("foo", 0, "barikoviev");Response<String> pipeString = p.get("fool");Response<Set<String>> sose = p.zrange("foo", 0, -1);p.sync(); int soseSize = sose.get().size();Set<String> setBack = sose.get();
發布/訂閱訂閱訊息

先建立一個JedisPubSub對象,然後使用Jedis對象調用subscribe方法即可,該方法需要傳入JedisPubSub對象;

MyListener listener = new MyListener(); //listener為JedisPubSub對象,監聽類jedis.subscribe(listener, "channel01");
發布訊息

發布訊息調用Jedis的publish方法即可;

jedis.publish(channel, message)

注意:subscribe方法是一個阻塞的操作,且發布和訂閱不能使用同一個Jedis對象

一個完整的例子

監聽事件類別:

package cn.edu.hdu.jedisdemo;import redis.clients.jedis.JedisPubSub;class MyListener extends JedisPubSub {    public void onMessage(String channel, String message) {        System.out.println("get a msg: " + "channel=" + channel + ", message=" + message);    }    public void onSubscribe(String channel, int subscribedChannels) {        System.out.println("channel:" + channel + ", subscribedChannels:" + subscribedChannels);    }    public void onUnsubscribe(String channel, int subscribedChannels) {        System.out.println("channel:" + channel + ", subscribedChannels:" + subscribedChannels);    }    public void onPSubscribe(String pattern, int subscribedChannels) {        System.out.println("pattern:" + pattern + ", subscribedChannels:" + subscribedChannels);    }    public void onPUnsubscribe(String pattern, int subscribedChannels) {        System.out.println("pattern:" + pattern + ", subscribedChannels:" + subscribedChannels);    }    public void onPMessage(String pattern, String channel, String message) {        System.out.println("pattern:" + pattern + ", channel:" + channel + ", message:" + message);    }}

main方法:

package cn.edu.hdu.jedisdemo;import java.util.Date;import java.util.concurrent.TimeUnit;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.JedisPoolConfig;public class App {    public static void main(String[] args) {        final JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost");            //兩個訂閱者            new Thread(new Runnable() {                @Override                public void run() {                    Jedis jedis = pool.getResource();                    MyListener listener = new MyListener();                    jedis.subscribe(listener, "channel01");                }            }).start();                        new Thread(new Runnable() {                @Override                public void run() {                    Jedis jedis = pool.getResource();                    MyListener listener = new MyListener(); //listener為JedisPubSub對象,監聽類                    jedis.subscribe(listener, "channel01");                }            }).start();            //一個發行者            new Thread(new Runnable() {                @Override                public void run() {                    //注意,訂閱使用的jedis對象與發布使用的jedis對象不能相同,否者運行時會報錯                    Jedis jedis = pool.getResource();                    while(true){                        try {                            TimeUnit.SECONDS.sleep(1);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                        String msg = new Date().toLocaleString();                        System.out.println("publish a msg:" + msg);                        jedis.publish("channel01", msg);                    }                }            }).start();                    //pool.close();    }}

執行結果:

channel:channel01, subscribedChannels:1
channel:channel01, subscribedChannels:1
publish a msg:2016-7-20 10:03:42
get a msg: channel=channel01, message=2016-7-20 10:03:42
get a msg: channel=channel01, message=2016-7-20 10:03:42
publish a msg:2016-7-20 10:03:43
get a msg: channel=channel01, message=2016-7-20 10:03:43
get a msg: channel=channel01, message=2016-7-20 10:03:43
publish a msg:2016-7-20 10:03:44
get a msg: channel=channel01, message=2016-7-20 10:03:44
get a msg: channel=channel01, message=2016-7-20 10:03:44 分布式ShardedJedis

ShardedJedis裡面採用了一致性雜湊的演算法,來決定每個key的儲存位置,主要用於分攤伺服器的壓力。

舉個簡單的例子:

首先,開啟三個redis伺服器,分別使用不同的連接埠(拷貝三份,使用不同的設定檔即可):6379、6380、6381

然後,編寫測試代碼:

package cn.edu.hdu.jedisdemo;import java.util.Arrays;import java.util.List;import redis.clients.jedis.Client;import redis.clients.jedis.JedisPoolConfig;import redis.clients.jedis.JedisShardInfo;import redis.clients.jedis.ShardedJedis;import redis.clients.jedis.ShardedJedisPool;public class App {    public static void main(String[] args) {        // 設定串連池的相關配置        JedisPoolConfig poolConfig = new JedisPoolConfig();        poolConfig.setMaxTotal(2);        poolConfig.setMaxIdle(1);        poolConfig.setMaxWaitMillis(2000);        poolConfig.setTestOnBorrow(false);        poolConfig.setTestOnReturn(false);        //設定Redis資訊        String host = "127.0.0.1";        JedisShardInfo shardInfo1 = new JedisShardInfo(host, 6379, 500);        JedisShardInfo shardInfo2 = new JedisShardInfo(host, 6380, 500);        JedisShardInfo shardInfo3 = new JedisShardInfo(host, 6381, 500);        //初始化ShardedJedisPool        List<JedisShardInfo> infoList = Arrays.asList(shardInfo1, shardInfo2, shardInfo3);        ShardedJedisPool jedisPool = new ShardedJedisPool(poolConfig, infoList);                //一些基本操作        try(ShardedJedis jedis = jedisPool.getResource()) {            jedis.set("test", "test");            String test = jedis.get("test");            System.out.println(test);        }        //查看        ShardedJedis jedis = jedisPool.getResource();        jedis.set("1111", "1111");        jedis.set("2222", "2222");        jedis.set("3333", "3333");        jedis.set("4444", "4444");        Client client1 = jedis.getShard("1111").getClient();        Client client2 = jedis.getShard("2222").getClient();        Client client3 = jedis.getShard("3333").getClient();        Client client4 = jedis.getShard("4444").getClient();        //列印key在哪個server中        System.out.println("1111 in server:" + client1.getHost() + " and port is:" + client1.getPort());        System.out.println("2222 in server:" + client2.getHost() + " and port is:" + client2.getPort());        System.out.println("3333 in server:" + client3.getHost() + " and port is:" + client3.getPort());        System.out.println("4444 in server:" + client4.getHost() + " and port is:" + client4.getPort());
jedis.close(); jedisPool.close(); }}

查看輸出結果:

test
1111 in server:127.0.0.1 and port is:6380
2222 in server:127.0.0.1 and port is:6379
3333 in server:127.0.0.1 and port is:6381
4444 in server:127.0.0.1 and port is:6381

 參考內容:

https://github.com/xetorthio/jedis/wiki/AdvancedUsage

http://www.cnblogs.com/coder2012/p/4401153.html

http://blog.csdn.net/lihao21/article/details/48370687

http://www.cnblogs.com/vhua/p/redis_1.html

Redis用戶端開發包:Jedis學習-進階應用程式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.