<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    聶永的博客

    記錄工作/學習的點點滴滴。

    Servlet 3.0筆記之Redis操作示范Retwis JAVA版

    最近學習Redis,一個目前風頭正勁的KEY-VALUE NOSQL,支持LIST、SET、MAP等格式存儲,某些操作竟然是原子級別,比如incr命令,相當驚艷。官方提供的一個Retwis(simple clone of Twitter)示范,證明了完全可以使用redis替代SQL數據庫存儲數據,真是一大開創性創新,挑戰人們的傳統思維模式,為之驚嘆!

    不過那是一個PHP版本,我下載到本地PHP但無法部署成功;還好有一個Retwis-RB示范,還提供一個在線版,試用之后,再下載源代碼,RUBY + Sinatra MVC結構,看的流口水,代碼那般簡潔。

    為體驗Redis,同時也為對比Ruby代碼,因此誕生了Retwis-JAVA,Retwis-RB的山寨版,因此其邏輯和HTML資源一致,再次表示對原作者Dan Lucraft的感謝。

    Retwis-JAVA,基于Servlet 3.0 + UrlRewrite + Freemarker + Jedis。示范運行在Tomcat 7中,redis為最新的2.22版本,jedis為redis的java客戶端操作框架。在Servlet 3.0規范中,對Url映射處理依然沒有進步,因此只能使用UrlRewrite框架讓部分url看起來友好一些。另外,項目沒有使用IOC容器框架,沒有使用MVC框架,代碼量稍微多些,代碼相對耦合一些。若使用Struts2 + Spring 代碼量會少一些。

    對涉及到的redis存儲結構,大致如下:


    涉及到的兩個對象很簡單:


    序列化后以二進制數據保存到redis中:

        private byte[] object2Bytes(V value) {
            
    if (value == null)
                
    return null;

            ByteArrayOutputStream arrayOutputStream 
    = new ByteArrayOutputStream();
            ObjectOutputStream outputStream;
            
    try {
                outputStream 
    = new ObjectOutputStream(arrayOutputStream);

                outputStream.writeObject(value);
            } 
    catch (IOException e) {
                e.printStackTrace();
            } 
    finally {
                
    try {
                    arrayOutputStream.close();
                } 
    catch (IOException e) {
                    e.printStackTrace();
                }
            }

            
    return arrayOutputStream.toByteArray();
        }


        
    public void save(String key, V value) {
            jedis.set(getKey(key), object2Bytes(value));
        }

    獲取用戶的timeline時,redis的LRANGE命令提供對list類型數據提供分頁操作:

        private List<Status> timeline(String targetId, int page) {
            
    if (page < 1)
                page 
    = 1;

            
    int startIndex = (page - 1* 10;
            
    int endIndex = page * 10;

            List
    <String> idList = super.jedis
                    .lrange(targetId, startIndex, endIndex);

            
    if (idList.isEmpty())
                
    return new ArrayList<Status>(0);

            List
    <Status> statusList = new ArrayList<Status>(idList.size());
            
    for (String id : idList) {
                Status status 
    = load(Long.valueOf(id));

                
    if (status == null)
                    
    continue;

                status.setUser(userService.load(status.getUid()));

                statusList.add(status);
            }

            
    return statusList;
        }

    很顯然,LRANGE取出了Status對象的ID,然后我們需要再次根據ID獲取對應的Status對象二進制數據,然后反序列化:

        public Status load(long id) {
            
    return super.get(getFormatId(id));
        }

        
    private String getFormatId(long id) {
            
    return String.format(STATUS_ID_FORMAT, id);
        }

        
    private static final String STATUS_ID_FORMAT = "status:id:%d";

        
    public V get(String key) {
            
    return byte2Object(jedis.get(getKey(key)));
        }

        @SuppressWarnings(
    "unchecked")
        
    private V byte2Object(byte[] bytes) {
            
    if (bytes == null || bytes.length == 0)
                
    return null;

            
    try {
                ObjectInputStream inputStream;
                inputStream 
    = new ObjectInputStream(new ByteArrayInputStream(bytes));
                Object obj 
    = inputStream.readObject();

                
    return (V) obj;
            } 
    catch (IOException e) {
                e.printStackTrace();
            } 
    catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

            
    return null;
        }

    以上使用JDK內置的序列化支持;更多序列化,可參考hessian、google protobuf等序列化框架,后者提供業界更為成熟的跨平臺、更為高效的序列化方案。更多代碼請參見附件。

    一些總結和思考:

    1. 不僅僅是緩存,替代SQL數據庫已完全成為可能,更高效,更經濟;雖然只是打開了一扇小的窗戶,但說不準以后人們會把大門打開。
    2. 實際環境中,可能最佳方式為SQL + NOSQL配合使用,互相彌補不足;還好,redis指令不算多,可速查,簡單易記。
    3. JAVA和RUBY代碼相比,有些重

    另:

    在線版,請參考 http://retwisrb.danlucraft.com/。那個誰誰,要運行范例,保證redis運行才行。

    Retwis-JAVA下載

    參考資料:

    Writing a simple Twitter clone with PHP and Redis

    https://github.com/xetorthio/jedis

    http://redis.io/commands

    posted on 2011-04-06 09:42 nieyong 閱讀(6128) 評論(0)  編輯  收藏 所屬分類: Servlet3

    公告

    所有文章皆為原創,若轉載請標明出處,謝謝~

    新浪微博,歡迎關注:

    導航

    <2011年4月>
    272829303112
    3456789
    10111213141516
    17181920212223
    24252627282930
    1234567

    統計

    常用鏈接

    留言簿(58)

    隨筆分類(130)

    隨筆檔案(151)

    個人收藏

    最新隨筆

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 久久经典免费视频| 亚洲喷奶水中文字幕电影| 日韩在线免费视频| 国产免费A∨在线播放| 亚洲综合一区无码精品| 亚洲男人第一av网站| 免费一级毛片在线观看| h视频在线免费看| 日韩免费电影网站| 国产精品内射视频免费| 国产AV日韩A∨亚洲AV电影| 99久久婷婷国产综合亚洲| 亚洲成a人片在线观看中文动漫| 国产成人亚洲综合| 国产一级淫片a免费播放口之 | 国产亚洲精aa成人网站| 妞干网手机免费视频| 午夜福利不卡片在线播放免费| 99久热只有精品视频免费看| 国产在线精品一区免费香蕉| 免费一级特黄特色大片| 久久久亚洲精华液精华液精华液 | 亚洲精品无码少妇30P| 久久久久se色偷偷亚洲精品av| 精品无码一区二区三区亚洲桃色| 久久亚洲国产午夜精品理论片 | 最近免费mv在线观看动漫| 一道本不卡免费视频| 污污免费在线观看| 草久免费在线观看网站| 国产亚洲精品精品精品| 久久精品亚洲日本波多野结衣| 亚洲欧好州第一的日产suv| 亚洲一久久久久久久久| 久久精品国产亚洲AV蜜臀色欲| 亚洲ts人妖网站| 亚洲熟妇无码AV| 国产成人亚洲精品播放器下载| 又大又硬又粗又黄的视频免费看| 人妖系列免费网站观看| 中文字幕免费在线播放|