Redis
页面静态化方案是一种解决商品并发高非常有效的手段,但是很多情况下我们还要用redis做缓存。
redis是目前非常流行的一款NoSql数据库。
1. NoSql
NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。
NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展
今天我们可以通过第三方平台(如:Google,Facebook等)可以很容易的访问和抓取数据。用户的个人信息,社交网络,地理位置,用户生成的数据和用户操作日志已经成倍的增加。我们如果要对这些用户数据进行挖掘,那SQL数据库已经不适合这些应用了, NoSQL 数据库的发展却能很好的处理这些大的数据。
NoSql相对于关系型数据库(Mysql)而言,关系型数据库的特点:数据库的结构是联系的,提前定义好,所有数据必须按照这个格式进行存储,即数据存储方式不能随便定义。而NoSql对数据格式没有特别严格的要求,且相对于关系数据库更加灵活
2. Redis
redis(主要用作缓存)
缓存:CPU的一级缓存、二级缓存。CPU运行速度非常快,瓶颈是内存和CPU之间的数据传输。CPU要运算还要从内存中读取数据,读到CPU里才能运算,数据传输非常慢,于是就加了缓存,把内存中的数据加载到缓存里,这样运算时不用去找内存,而是去快速缓存去找,提升效率很快。
IO流:缓冲流,可以有效提高IO读取效率,减少与磁盘交互次数
查数据库,请求到达tomcat,tomcat每次都要查数据库,数据库的并发相对较大,因为要经过磁盘io,并发能力差;如果我们把请求在前边通过redis做一个拦截,那么请求到达以后不是去查数据库,而是直接去查redis,而redis并发是非常强的,单机的并发能力能达到六七万,性能非常好。缓存可以有效的提高程序运行的速度
2.1 特性
2.2 Redis与Memcache
Redis与Memcache是目前非常流行的两种NoSql数据库,都可以用于服务端缓存.
- 从实现来看:
- redis:单线程
- Memcache:多线程(多线程运行会对CPU有一定损耗,因为CPU要在线程间进行切换)
- 从存储方式来看:
- redis:支持数据持久化和主从备份,数据更安全
- memcache:数据存于内存,没有持久化功能
- 从功能来看:
- redis:除了基本的k-v结构外,支持多种其他复杂结构,事务等高级功能。
- memcache:只支持基本的k-v结构(纯粹用来做缓存)
- 从可用性看:
- redis:支持主从备份、数据分片、哨兵监控
- memcache:没有分片功能,需要从客户端支持
2.3 Redis指令
可见,Redis中存储数据结构都是类似java的map类型,Redis不同数据类型,只是‘map’的值的类型不同
2.3.1 通用指令
redis默认有16个库,角标:0-15
select: 切换库
persist key:移除给定key的生存时间
2.3.2 字符串指令
2.3.3 hash结构命令
HSET key field value:将哈希表key中的字段field的值设为value
Hget key field:用于返回哈希表中指定字段的值
HGETALL key: 获取在哈希表中指定key的所有字段和值
HKEYS: 获取所有哈希表中的字段
HVALS: 获取哈希表中所有值
HDEL:删除哈希表key中的一个或多个字段
2.4 Redis template
2.4.1 Spring Data Redis
官网:http://projects.spring.io/spring-data-redis/
Spring Data Redis,是Spring Data 家族的一部分。 对Jedis客户端进行了封装,与spring进行了整合。可以非常方便的来实现redis的配置和操作。
2.4.2 RedisTemplate基本操作
Spring Data Redis 提供了一个工具类:RedisTemplate。里面封装了对于Redis的五种数据结构的各种操作,包括:
- redisTemplate.opsForValue() :操作字符串
- redisTemplate.opsForHash() :操作hash
- redisTemplate.opsForList():操作list
- redisTemplate.opsForSet():操作set
- redisTemplate.opsForZSet():操作zset
其它一些通用命令,如expire,可以通过redisTemplate.xx()来直接调用
5种结构:
- String:等同于java中的,Map<String,String>
- list:等同于java中的Map<String,List>
- set:等同于java中的Map<String,Set>
- sort_set:可排序的set
- hash:等同于java中的:`Map<String,Map<String,String>>
2.4.3 StringRedisTemplate
RedisTemplate在创建时,可以指定其泛型类型:
- K:代表key 的数据类型
- V: 代表value的数据类型
注意:这里的类型不是Redis中存储的数据类型,而是Java中的数据类型,RedisTemplate会自动将Java类型转为Redis支持的数据类型:字符串、字节、二二进制等等。
不过RedisTemplate默认会采用JDK自带的序列化(Serialize)来对对象进行转换。生成的数据十分庞大,因此一般我们都会指定key和value为String类型,这样就由我们自己把对象序列化为json字符串来存储即可。
因为大部分情况下,我们都会使用key和value都为String的RedisTemplate,因此Spring就默认提供了这样一个实现:
2.5 使用配置
2.5.1 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.5.2 配置文件
2.5 3 测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes = LyUserService.class)
public class RedisTest {
@Autowired
private StringRedisTemplate redisTemplate;
@Test
public void testRedis() {
// 存储数据
this.redisTemplate.opsForValue().set("key1", "value1");
// 获取数据
String val = this.redisTemplate.opsForValue().get("key1");
System.out.println("val = " + val);
}
@Test
public void testRedis2() {
// 存储数据,并指定剩余生命时间,5小时
this.redisTemplate.opsForValue().set("key2", "value2",
5, TimeUnit.HOURS);
}
@Test
public void testHash(){
BoundHashOperations<String, Object, Object> hashOps =
this.redisTemplate.boundHashOps("user");
// 操作hash数据
hashOps.put("name", "jack");
hashOps.put("age", "21");
// 获取单个数据
Object name = hashOps.get("name");
System.out.println("name = " + name);
// 获取所有数据
Map<Object, Object> map = hashOps.entries();
for (Map.Entry<Object, Object> me : map.entrySet()) {
System.out.println(me.getKey() + " : " + me.getValue());
}
}
}
3. Redis与MySQL
-
mysql是关系型数据库,而redis为非关系型数据库
-
mysql用于持久化的存储数据到硬盘,功能强大,但是速度较慢;
redis用于存储使用较为频繁的数据到缓存中,读取速度快
-
redis读写能力为2W/s
mysql读能力5K/s、写能力为3K/s
数据上看redis性能碾压mysql
mysql和redis两者功能并不冲突,可以协同一起使用,效率会更高