一、安装
先安装gcc工具(gcc是linux下的一个编译器,可以用来编译c、c++等代码):
yum -y install gcc //-y表示自动安装
wget http://download.redis.io/releases/redis-2.8.17.tar.gz //下载redis安装包(下
载到usr/local)
tar xzf redis-2.8.17.tar.gz
cd redis-2.8.17 //进入redis安装包下
make(make MALLOC=libc) //编译命令
src/redis-server //启动服务器
src/redis-cli //启动客户端
二、数据类型
String、hash、list、set、zset
三、存储字符串
set key value
get key
可以设置失效时间
set key value EX 10 //10秒钟之后失效
四、存储哈希值
//hmset是存储hash值的指令,
//user是当前hash的key
//name "zhangsan" age 23 sex "nan" 是 key对应的值
127.0.0.1:6379> hmset user name "zhangsan" age 23 sex "nan"
OK
//hmget获取hash中的某一个属性的值
127.0.0.1:6379> hmget user name
1) "zhangsan"
127.0.0.1:6379> hmget user age
1) "23"
//hgetall是获取hash中的所有属性对应的值
127.0.0.1:6379> hgetall user
1) "name"
2) "zhangsan"
3) "age"
4) "23"
5) "sex"
6) "nan"
五、存储List有序列表
//lpush用来存储一个列表的命令。interesting是列表的名称,"basketball"列表中的值
127.0.0.1:6379> lpush interesting "basketball"
(integer) 1
127.0.0.1:6379> lpush interesting "football" "ball"
(integer) 3
//lrange输出列表中的数据的命令, interesting就是列表的名称 。 0 2是列表的开始输出索引和结
束索引。
127.0.0.1:6379> lrange interesting 0 2
1) "ball"
2) "football"
3) "basketball"
六、存储Set集合(无序集合)
sadd key member //存数据
smembers key //取数据
案例:
127.0.0.1:6379> sadd strset "a" "b" "c"
(integer) 3
127.0.0.1:6379> smembers strset
1) "b"
2) "c"
3) "a"
七、存储zset集合(有序集合)
zadd key score member (score是一个数字,zset就是通过这个数字进行排序,可以重复)
ZRANGEBYSCORE key 0 1000 //通过分数排序输出
有序集合是按照score进行排序
八、安全配置
config set requirepass 123456 //配置redis的密码
config get requirepass //查看密码
验证密码:auth 123456
带密码登录:./redis-cli -h 127.0.0.1 -p 6379 -a 123456 // -h表示主机IP,-p端
口,-a密码
永久密码设置:
修改redis安装目录下的redis.conf文件中的requirepass属性,比如:
requirepass 123456
修改完成之后保存退出,让配置生效的启动redis的命令如下:
./src/redis-server redis.conf
九、秒杀活动
1、导包:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.5.0</version>
</dependency>
</dependencies>
2、秒杀:
public String transaction(String id){
String msg = "";
List<Object> list = redisTemplate.execute(new SessionCallback<List<Object>>() {
@Override
public List<Object> execute(RedisOperations operations) throws DataAccessException {
//加锁
operations.watch(id);
Integer goods_num = (Integer) operations.boundValueOps(id).get();
//开启事务
operations.multi();
if(goods_num > 0) {
operations.boundValueOps(id).set(goods_num-1);
}
return operations.exec();//自动释放锁
}
});
if (list==null || list.isEmpty()) {
msg ="已抢光";
System.out.println(Thread.currentThread().getName() + ":失败");
} else {
msg ="购买成功";
System.out.println(Thread.currentThread().getName() + ":"+list.get(0));
}
return msg;
}
3、缓存穿透:
public String demo(){
//查询数据之前先查询缓存
BoundListOperations<String, String> listOperations = redisTemplate.boundListOps("roles");
Long size = listOperations.size();
//1、查询缓存
List<String> roles = redisTemplate.boundListOps("roles").range(0, size);
//2、判断缓存中是否存在需要的数据
if (roles == null || roles.isEmpty()) {
//避免缓存穿透,所以加锁,排队访问
System.out.println("---排队----");
synchronized (this) {
//双重缓存检测机制
roles = redisTemplate.boundListOps(ApplicationConstant.REDIS.KEY_ROLES).range(0, size);
if (roles == null || roles.isEmpty()) {
System.out.println("---------------");
//不存在,则查询数据库
roles = rolesDAO.queryRolesByUsername("001");
//数据库中的数据查到之后,再写入缓存,方便下次查询的时候直接从缓冲中取数据
//1、此处不论数据库查询出来的数据是否为空,都写入缓存,避免故意使用无效数据进行恶意攻击导致穿透
//如果上一条不停再缓存中存储无效key,会导致缓存不断增加,从而内存耗尽。导致正常数据无处安身。
if (roles == null || roles.isEmpty()) {
//如果数据库没有此数据,则先存入数据库,然后设置过期时间
redisTemplate.boundValueOps(ApplicationConstant.REDIS.KEY_ROLES).set("",5,TimeUnit.SECONDS);
} else {
redisTemplate.opsForList().leftPushAll(ApplicationConstant.REDIS.KEY_ROLES, roles);
}
}
}
} else {
System.out.println(">>>>>>>>>>>>>>>>>>>");
}
return "redis";
}
4、展示热销商品:
public List<Goods> showHotGoods(){
Map<Goods,Integer> goods = redisTemplate.opsForHash().entries("hotGoods");
if(goods.isEmpty()){
Map<Goods,Integer> goodsIntegerMap = new HashMap<>();
List<ShoppingCartBean> hotGoods = goodsDAO.findHotGoods();
for (ShoppingCartBean cartBean : hotGoods) {
Goods goods1 = goodsDAO.findByGoodsId(cartBean.getGoodId());
goodsIntegerMap.put(goods1,cartBean.getGoodCount());
}
redisTemplate.opsForHash().putAll("hotGoods",goodsIntegerMap);
}
List<Goods> hotGoodsList = new ArrayList<>();
Map<Goods,Integer> hotGoods = redisTemplate.opsForHash().entries("hotGoods");
for (Goods o : hotGoods.keySet()) {
hotGoodsList.add(o);
}
return hotGoodsList;
}
5、服务器启动时构建缓存:
public class RedisInitListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("#############初始化缓存##############");
ServletContext servletContext = servletContextEvent.getServletContext();
WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
AdminDAO adminDAO = (AdminDAO) applicationContext.getBean("adminDAO");
AdmireDAO admireDAO = (AdmireDAO) applicationContext.getBean("admireDAO");
RedisTemplate<String,String> redisTemplate = (RedisTemplate<String, String>) applicationContext.getBean("redisTemplate");
List<Admins> adminIdList = adminDAO.findAllAdminId();
//创建所有登录用户的点赞信息的缓存
for (Admins admins : adminIdList) {
//当前用户给谁点过赞
List<Admire> likesById = admireDAO.findLikesById(admins.getId());
BoundSetOperations<String, String> setOps = redisTemplate.boundSetOps(admins.getUsername());
for (Admire admire : likesById) {
setOps.add(admire.getTruename());
}
}
//所有女孩的信息的缓存
BoundSetOperations<String, String> setOps = redisTemplate.boundSetOps("allAdmireKey");
List<Admire> admireList = admireDAO.findAll();
System.out.println("======================"+admireList);
for (Admire admire : admireList) {
BoundHashOperations<String, Object, Object> operations = redisTemplate.boundHashOps(admire.getTruename());
operations.put("admireId",admire.getAdmireId());
operations.put("truename",admire.getTruename());
operations.put("sex",admire.getSex());
operations.put("birth",admire.getBirth());
operations.put("job",admire.getJob());
operations.put("marital",admire.getMarital());
operations.put("likes",admire.getLikes());
operations.put("pic",admire.getPic());
setOps.add(admire.getTruename());
}
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}