天天看點

電商平台-redis緩存在商品中的設計與架構

說明:Java開源生鮮電商平台-redis緩存在商品中的設計與架構。

1. 各種計數,商品次元計數和使用者次元計數

  說起電商,肯定離不開商品,而附帶商品有各種計數(喜歡數,評論數,鑒定數,浏覽數,etc),Redis的指令都是原子性的,你可以輕松地利用INCR,DECR等指令來計數。

  • 商品次元計數(喜歡數,評論數,鑒定數,浏覽數,etc)

    采用Redis 的類型: 

Hash

. 如果你對redis資料類型不太熟悉,可以參考 http://redis.io/topics/data-types-intro。為product定義個key 

product:

,為每種數值定義hashkey, 譬如喜歡數

like

jedis.hset("product:1", "like", "5");

jedis.hincrBy("product:1", "like", 1);//喜歡加一

System.out.print(jedis.hget("product:1", "like"));
           
  • 使用者次元計數(動态數、關注數、粉絲數、喜歡商品數、發帖數 等)

     使用者次元計數同商品次元計數都采用 

Hash

. 為User定義個key 

user:

,為每種數值定義hashkey, 譬如關注數

follow

jedis.hset("user:1", "follow", "5");

jedis.hincrBy("user:1", "follow", 1);//關注數加一

System.out.print(jedis.hget("user:1", "follow"));
           

2. 存儲社交關系

     譬如将用戶的好友/粉絲/關注,可以存在一個

sorted set

中,score可以是timestamp,這樣求兩個人的共同好友的操作,可能就隻需要用求交集指令即可。

jedis.zadd("user:1000:friends", System.currentTimeMillis(), "user:1001");

//uid為1000使用者和uid為1001是朋友 , score值設定時間戳

jedis.zadd("user:1000:friends", System.currentTimeMillis(), "user:1002");

//uid為1000使用者和uid為1002是朋友 , score值設定時間戳


jedis.zadd("user:2000:friends", System.currentTimeMillis(), "user:1001");

jedis.zadd("user:2000:friends", System.currentTimeMillis(), "user:1003");


jedis.zinterstore("com_friends:1000:2000", "user:1000:friends", "user:2000:friends");

System.out.println(jedis.zrange("com_friends:1000:2000", 0, -1));
           

3. 用作緩存代替memcached(商品清單,評論清單,@提示清單,etc)

       相對memcached 簡單的key-value存儲來說,redis衆多的資料結構(list,set,sorted set,hash, etc)可以更友善cache各種業務資料,性能也不亞于memcached。

4. 反spam系統(評論,釋出商品,論壇發貼,etc)

    作為一個電商網站被各種spam攻擊是少不免(垃圾評論、釋出垃圾商品、廣告、刷自家商品排名等),針對這些spam制定一系列anti-spam規則,其中有些規則可以利用redis做實時分

析,譬如:1分鐘評論不得超過2次、5分鐘評論少于5次等(更多機制/規則需要結合drools )。

    采用

sorted set

将最近一天使用者操作記錄起來(為什麼不全部記錄?節省memory,全部操作會記錄到log,後續利用hadoop進行更全面分析統計)

if(!jedis.exists("user:1000:comment")){//還沒有評論

jedis.zadd("user:1000:comment", System.currentTimeMillis(), "uid為1000的評論内容");

System.out.println(jedis.zrange("user:1000:comment", 0, -1));

}else{

//擷取一分鐘内的評論記錄

Set<String> result = jedis.zrangeByScore("user:1000:comment", System.currentTimeMillis() - 60 * 1000, System.currentTimeMillis());

if(!result.isEmpty()){

System.out.println("1分鐘内不能評論兩次");

}else{

jedis.zadd("user:1000:comment", System.currentTimeMillis(), "uid為1000的評論内容"+System.currentTimeMillis());

System.out.println(jedis.zrange("user:1000:comment", 0, -1));

}

}
           

5. 使用者Timeline/Feeds

  應用于關注的人、主題、品牌及專欄,redis在這邊主要當作cache使用

jedis.zadd("user:2000:feed:topic", System.currentTimeMillis(), "13topic" + System.currentTimeMillis());

//score為timestamp uid為2000的使用者關注tid為13的topic

jedis.expire("user:2000:feed:topic", 10);

//關注有效期為10秒

System.out.println(jedis.zrange("user:2000:feed:topic", 0, -1));
           

6. 最新清單&排行榜

  用于記錄使用者剛剛喜歡的商品最新清單or排行榜 等業務場景

jedis.zadd("user:1000:product:like", System.currentTimeMillis(), "003");

Thread.currentThread();

Thread.sleep(10);

jedis.zadd("user:1000:product:like", System.currentTimeMillis(), "001");

Thread.sleep(10);

jedis.zadd("user:1000:product:like", System.currentTimeMillis(), "004");

Thread.sleep(10);

jedis.zadd("user:1000:product:like", System.currentTimeMillis(), "002");

Thread.sleep(10);


//預設喜歡時間升序排列

Set<String> result = jedis.zrange("user:1000:product:like", 0, -1);

System.out.println(result);


//按喜歡時間降序排列

result = jedis.zrevrange("user:1000:product:like", 0, -1);

System.out.println(result);
           
[003, 001, 004, 002]

[002, 004, 001, 003]
           

7. 消息通知

  采用Hash結構對消息通知業務場景計數

//設定1條未讀系統消息

jedis.hset("user:1000:message:num", "sysmessagenum", "1");

jedis.sadd("user:1000:message:content", "第一條未讀資訊");

//未讀系統消息+1

jedis.hincrBy("user:1000:message:num", "sysmessagenum", 1);

jedis.sadd("user:1000:message:content", "第二條未讀資訊");

//檢視所有消息通知數量

System.out.println(jedis.hgetAll("user:1000:message:num"));

//檢視所有消息通知内容

System.out.println(jedis.smembers("user:1000:message:content"));
           
{sysmessagenum=2}

[第二條未讀資訊, 第一條未讀資訊]
           

繼續閱讀