1. spring-data-redis简介 
封装了一下redis的客户端,使得使用起来更方便。 
优点是把客户端连接放到一个连接池里,从而提高性能。还有就是可以不同的客户端之间实现切换,而不用改一行代码(Spring惯用的一个手法)。 
本文写作时最新版是1.3, 
目前支持下面4种java客户端,可以自由切换而不用改代码。

2. twitter简介 
twitter如果没用过的话,可以理解成类似于国内的新浪微博。因为微博的访问量和使用人数极大,用传统的关系型数据库支撑不了,所以有了用redis这种非关系型数据库的架构设计。 
本文我们将用spring-data-redis来实现一个类似twitter的网站。

3. 环境 
本人亲测通过环境 
jdk 1.6.0_45 64bit 
gradle 1.7 
tomcat 7.0.35 
redis 2.8.11 win64 
jedis 2.5.1 
spring 3.2.9 
spring-data-redis 1.3.0

4. 先动手操作 
4.1 首先git clone以下项目 
https://github.com/spring-projects/spring-data-keyvalue-examples/tree/master/retwisj

4.2 本人做了一些修改,一些3pp改成本文写作时最新的版本 
build.gradle

  1. compile "redis.clients:jedis:2.5.1"

gradle.properties

  1. springVersion = 3.2.9.RELEASE
  2. springRedisVersion = 1.3.0.RELEASE

4.3 编译

  1. gradle build

4.4 将retwisj.war放入tomcat的webapp目录下,启动tomcat

4.5 访问http://localhost:8080/retwisj 
花几分钟上去玩一下,熟悉一下功能。 
好了,我们已经做好了一个微博网站了。玩好了我们简单分析一下代码实现。

5. 实现分析

5.1 表结构设计

5.1.1 用户(User)

用以前的关系型数据库设计是这样的

Key Username Password
1 springrod interface21
2 costinl this is fun

而用redis的则变成了这样

Key Type Value
uid:1 hash {name: springrod, pass: interface21}
uid:2 hash {name: costinl, pass: secret}

将用户的名字和密码作为一个hash存入 
对应的redis原生命令是

  1. HMSET user:1 name springrod pass interface21

uid是自增长的,可以用redis的INCR来实现,这是一个原子操作

  1. INCR global:uid
Key Type Value
global:uid string 2

我们要保存username和uid的对应关系,比如一个user登录时,我们要得到他的uid。可以创建一个倒转的key来实现此功能。user:[name]:uid 
还创建了一个users用来保存所有uid的list

Key Type Value
user:springrod:uid string 1
user:costinl:uid string 2
users list {1, 2}

5.1.2 微博(Post)

同样的,用global:pid来记录自增长的post id

Key Type Value
global:pid string 2

将微博的内容、时间和作者作为一个hash存入

Key Type Value
pid:1 hash {content: Hello World, time: 1301931414757, uid: 1}
pid:2 hash {content: Working on some cool stuff, time: 1301931414897, uid: 1}
pid:3 hash {content: Checking out RetwisJ, time: 1301931454897, uid: 2}

某个用户的所有微博

Key Type Value
uid:1:posts list {1, 2}
uid:2:posts list {3}

所有微博列表(Timeline)

Key Type Value
timeline list {1, 2, 3}

5.1.3 关系(粉丝(Follower),关注(Following))

比如user2关注了user1,则user2是user1的粉丝, 
user3也关注了user1, 
则user1被user2,user3所关注

Key Type Value
uid:1:followers set {2,3}
uid:2:following set {1}
uid:3:following set {1}

新浪微博上姚晨的粉丝有7000万,光记录她一个人的粉丝就要7000万条记录。 
如果用传统的关系型数据库实现,压力很大。

5.2 安全验证 
我们不用session来跟踪用户,而用cookie。 
每当用户登录后,为他生成一个随机数(令牌),发给该用户,让他作为cookie保存,这个cookie用来验证用户的身份。 
同样的存储一个倒转的key,可以根据cookie来得到uid

Key Type Value
uid:2:auth string {fea5e81ac8ca77622bed1c2132a021f9}
auth:fea5e81ac8ca77622bed1c2132a021f9 string {2}

5.3 包的结构

org.springframework.data.redis.sample.retwisj.web web层
org.springframework.data.redis.sample.retwisj.redis 持久层
org.springframework.data.redis.sample.retwisj 领域层

5.4 使用redisTemplate 
applicationContext-redis.xml

  1. <beans>
  2. <context:property-placeholder location="classpath:redis.properties"/>
  3. <!-- Redis client 这里就是不改代码实现不同客户端切换的地方了,我们用jedis-->
  4. <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
  5. p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"/>
  6. <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"
  7. p:connection-factory-ref="connectionFactory"/>
  8. <context:annotation-config />
  9. <context:component-scan base-package="org.springframework.data.redis.samples"/>
  10. </beans>

5.5 web层 
采用spring MVC和JSP

5.5.1 Controller层 
RetwisController

5.5.2 CookieInterceptor 
对于用户验证,采用cookie的方式,写了一个Spring MVC的拦截器

  1. public class CookieInterceptor extends HandlerInterceptorAdapter

并在retwisj-servlet.xml里配置

  1. <mvc:interceptors>
  2. <bean class="org.springframework.data.redis.samples.retwisj.web.CookieInterceptor" />
  3. </mvc:interceptors>

执行效果就是在客户端保存了一个叫"retwisauth"的cookie,保存了用户的令牌。

5.5.3 i18

CookieLocaleResolver把语言作为cookie存在客户端

  1. <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/>

执行效果就是在客户端保存了一个叫"org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE"的cookie,保存了语言。

LocaleChangeInterceptor可以用来变更语言

  1. <mvc:interceptors>
  2. <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/>
  3. </mvc:interceptors>

这样就可以通过http://localhost:8080/retwisj/?lang=cn来变更语言

5.6 持久层 
RetwisRepository

如下代码示例了如何用intersect来找出2个用户相同的粉丝

  1. private RedisSet<String> following(String uid) {
  2. return new DefaultRedisSet<String>(KeyUtils.following(uid), template);
  3. }
  4. public List<String> commonFollowers(String uid, String targetUid) {
  5. RedisSet<String> tempSet = following(uid).intersectAndStore(following(targetUid),
  6. KeyUtils.commonFollowers(uid, targetUid));
  7. tempSet.expire(5, TimeUnit.SECONDS);
  8. return covertUidsToNames(tempSet.getKey());
  9. }

如下代码示例了用RedisAtomicLong实现自增长的id,BoundHashOperations来存储用户的用户名和密码

  1. public String addUser(String name, String password) {
  2. String uid = String.valueOf(userIdCounter.incrementAndGet());
  3. // save user as hash
  4. // uid -> user
  5. BoundHashOperations<String, String, String> userOps = template.boundHashOps(KeyUtils.uid(uid));
  6. userOps.put("name", name);
  7. userOps.put("pass", password);
  8. valueOps.set(KeyUtils.user(name), uid);
  9. users.addFirst(name);
  10. return addAuth(name);
  11. }
 http://xpenxpen.iteye.com/blog/2082966

用spring-data-redis实现类似twitter的网站(转)的更多相关文章

  1. spring mvc Spring Data Redis RedisTemplate [转]

    http://maven.springframework.org/release/org/springframework/data/spring-data-redis/(spring-data包下载) ...

  2. Spring Data Redis简介以及项目Demo,RedisTemplate和 Serializer详解

    一.概念简介: Redis: Redis是一款开源的Key-Value数据库,运行在内存中,由ANSI C编写,详细的信息在Redis官网上面有,因为我自己通过google等各种渠道去学习Redis, ...

  3. spring data redis 理解

    前言 Spring Data Redis project,应用了Spring概念来开发使用键值形式的数据存储的解决方案.我们(官方)提供了一个 "template" ,这是一个高级 ...

  4. Spring Data Redis 让 NoSQL 快如闪电(2)

    [编者按]本文作者为 Xinyu Liu,文章的第一部分重点概述了 Redis 方方面面的特性.在第二部分,将介绍详细的用例.文章系国内 ITOM 管理平台 OneAPM 编译呈现. 把 Redis ...

  5. Spring Data Redis学习

    本文是从为知笔记上复制过来的,懒得调整格式了,为知笔记版本是带格式的,内容也比这里全.点这里 为知笔记版本 Spring Data Redis 学习 Version 1.8.4.Release 前言 ...

  6. Redis(八):spring data redis 理解

    前言 Spring Data Redis project,应用了Spring概念来开发使用键值形式的数据存储的解决方案.我们(官方)提供了一个 "template" ,这是一个高级 ...

  7. 使用Spring Data Redis操作Redis(集群版)

    说明:请注意Spring Data Redis的版本以及Spring的版本!最新版本的Spring Data Redis已经去除Jedis的依赖包,需要自行引入,这个是个坑点.并且会与一些低版本的Sp ...

  8. Spring Data Redis整体介绍 (一)

    为什么使用Spring Data Redis 首先Spring Data Redis 是Spring 框架提供的用于操作Redis的客户端. Spring框架是一个全栈Java程序框架,通过DI.AO ...

  9. spring data redis RedisTemplate操作redis相关用法

    http://blog.mkfree.com/posts/515835d1975a30cc561dc35d spring-data-redis API:http://docs.spring.io/sp ...

  10. Spring Data Redis—Pub/Sub(附Web项目源码)

    一.发布和订阅机制 当一个客户端通过 PUBLISH 命令向订阅者发送信息的时候,我们称这个客户端为发布者(publisher). 而当一个客户端使用 SUBSCRIBE 或者 PSUBSCRIBE ...

随机推荐

  1. CentOS6.4关闭触控板

    1. 检查是否安装xorg-x11-app; rpm -qa xorg-x11-apps 如果没有安装使用下面命令安装xorg-x11-app yum install xorg-x11-apps 2. ...

  2. 免费的HTML5连载来了《HTML5网页开发实例具体解释》连载(六)媒体查询

    响应式设计的还有一个重要技术手段是媒体查询.假设仅仅是简单的设计一个流式布局系统,那么能够保证每一个网格按比例的放大和缩小,但有可能会使得在小屏幕下(如手机设备)网格太小而严重影响阅读,这种设计称不上 ...

  3. 安装centos7注意事项

    1,安装centos7注意1和l的区分 2,每一次对/boot/grub2/或者/boot/grub或者/etc/grub/下的文件修改一定要重新编译配置文件sudo grub2-mkconfig - ...

  4. django-model-utils

    一个普通例子: todos = Todo.objects.filter(owner=request.user).filter(is_done=False).filter(priority=1) 弊端: ...

  5. 腾讯QQ:异地登陆也被封号,你们是怎么决策的???

    此文我想放到首页,让很多其它的人看到,更期待有人能解释一下.希望管理员给开绿灯. 今天真是费解,我的手机号是青岛的.可是我在武汉工作,因为是3G的卡,全国没有漫游,打电话也没多少钱,所以就没换号. 谁 ...

  6. eclipse、MyEclipse实现批量改动文件编码

    在使用eclipse或MyEclipse编程时,常常遇到部分文件打开后出现乱码的情况(特别是在导入项目后) 1:右击项目选择properties->Resource>Other选择UTF- ...

  7. C# 课堂总结2-数据类型及转换方式

    一.输入输出语句 Console.ReadLine(); 会等待直到用户按下回车,一次读入一行Console.ReadKey(); 则是等待用户按下任意键,一次读入一个字符. 二.数据类型 主要掌握: ...

  8. 1076: [SCOI2008]奖励关( dp )

    期望状压dp.... ------------------------------------------------------------------ #include<cstdio> ...

  9. struts+hibernate 请求数据库增删改查(小项目实例)

      StudentAction.java package com.action; import java.util.ArrayList; import java.util.List; import j ...

  10. 浅尝key-value数据库(二)——MongoDB的优与劣

    浅尝key-value数据库(二)——MongoDB的优与劣 MongoDB的名字取自英文单词"humongous"的中间五个字母,是一个C++开发的基于分布式文件存储的数据库开源 ...