redis

NoSQL

NoSQL,Not Only SQL(不仅仅是SQL,不用sql语言操作的数据库),泛指非关系型的数据库,换言之不用SQL语句操作的数据库。

  • 关系型数据库:以表为单位管理数据,表与表之间存在某种关联关系
  • 非关系型数据库:数据与数据之间没有关系,数据就是以键值对形式存储,通过键获取到值

web1.0 2000年左右,网页就是一个静态的html页面,用不到数据库

web2.0 动态页面,页面上显示的数据,是动态从数据库中取的,用户可以评论

web3.0 用户参与信息创造 头条,抖音 信息量爆炸, 电商,节日 ,秒杀,抢购....

现在数据量越来越大,传统的系统架构支撑不了了。

关系型数据库瓶颈:

  • 连接数量有限
  • IO读写速度(数据在硬盘上存储)

关系型数据库在web2.0之后存在一些问题?

关系型数据库数据都是以特定的关系存在硬盘上的,随着网站的访问量有时候会激增(抢票,秒杀,抢购),在很短的时间内有大量的用户访问,导致数据库压力非常大,会导致关系型数据库崩溃。可以借助缓存(redis),把数据查询出来后,先缓存起来,每次取数据,可以从缓存中取到。但是关系型数据库还是不能被淘汰的,是数据关系存储的基本。(注册用户账号、商品信息、订单信息)

在关系型数据库的基础上,添加非关系型数据库进行数据缓存使用,减少关系型数据库的压力,两者配合使用,相互之间弥补缺点。

redis特点:

  1. 结构简单:(键:值的存储方式,没有表与表之间的固定信息。值的数据结构多样化)
  2. 性能高:Redis数据默认存储在内存中,读的速度是110000次/s,写的速度是81000次/s
  3. 支持数据持久化(临时在硬盘上的备份)

Linux安装redis

1.上传源码包

redis_第1张图片

2.解压

redis_第2张图片

3.进入到解压后的源码包中,make本地编译源码

redis_第3张图片

4.创建文件夹:mkdir -p /opt/redis,最终将redis安装到opt/redis

5.安装到指定位置 make install PREFIX=/opt/redis

redis_第4张图片

 6.进入到/opt/redis/bin,然后./redis-server启动redis服务

redis_第5张图片

redis基本设置

主要修改三点

  • 设置redis服务启动后,处于后台运行,这样就不影响我们正常的其他操作
  • 设置远程访问
  • 为redis设置连接密码

进入到redis源码包 redis-6.0.8,里面有个redis.conf的配置文件,将此文件复制到/opt/redis/bin中

redis_第6张图片

修改redis.conf文件:vim redis.conf,修改三个地方

(1)注释绑定的id,这样就可以远程访问了。默认只能本机访问。

redis_第7张图片

(2)开启后台运行:daemonize no 改为 daemonize yes

redis_第8张图片

(3)设置密码:requirepass 密码

文件内查找:/你搜索的内容,回车,n下一个,N上一个

N 上一个.

redis_第9张图片

启动命令:./redis-server redis.conf

查看 Redis 运行状态:ps -ef | grep redis

redis_第10张图片

此时redis服务器在后台已启动。

进入到redis客户端模式:./redis-cli(/opt/redis/bin中)

输入密码:auth 密码

测试:ping

ctrl+c 退出客户端模式

redis_第11张图片

在windows安装客户端工具,远程连接测试redis是否成功。(在此之前6379端口要放行)

redis_第12张图片

进入到客户端模式,进行常用的数据类型操作

使用kill -9 进程号,停止Redis服务

redis_第13张图片

redis数据类型

值的5 种基本常用类型:

string(字符串)、hash(哈希)、list(列表)、set(集合 )、zset(sorted set:有序集合)

redis_第14张图片

redis中的数据是以键值对存储,key都是String类型,这里所有说的数5中基本类型指的是值的类型

1、String(字符串)

string类型是redis最基本的数据类型,一个key对应一个value,它的值最大能存储512MB。

string类型是二进制安全的。可以包含任何数据,比如jpg图片或者序列化的对象。

1.1 单值缓存

set key value:设置一个键值对(键不能重复)

键不能重复,key为name的Tom把之前的Jim覆盖了

redis_第15张图片

get key:通过键获取值

del key:删除键

keys *:查看redis中所有的键

注意:虽然是字符串类型,但是可以存储图片-->base64、序列化的对象(json格式对象)

1.2 对象缓存(不对对象中数据操作时可以使用)

set user {name:jim,age:20}(值为json格式的字符串)

 

1.3 计数器

记录点赞、浏览量这种操作,可以在Redis中进行,不需要在关系型数据库mysql中进行

set newsid1 0 设置文章访问量

incr newsid1 自增1

decr newsid1 自减1

get newsid1 获得值

 redis_第16张图片

1.4 Web集群 session共享

session+redis,实现session共享

2、Hash(哈希)

hash是一个string类型的field和value的映射表,hash适合存储对象数据,而且可以对数据进行修改。

redis_第17张图片

  • hset key field value:存储一个哈希表key的键值;如果已经存在为修改操作
  • hmset key field1 value1 [field2 value2 …]:存储多个键值对

redis_第18张图片

 

  • hget key field:获取哈希表 key 对应的 field 键值
  • hmget key field [field …]:批量获取哈希表 key 中多个 field 键值

redis_第19张图片

  • hdel key field [field …]:删除哈希表 key 中的 field 键值hlen key 返回哈希表 key 中的 field 的数量

  • hgetall key:返回哈希表key中所有的键值

redis_第20张图片 

  • hincrby key field 增加的值(减少为负数)

实际用法:存储一个购物车信息

  1. 以用户id为key
  2. 商品id为field
  3. 商品数量为value

购物车操作

  1. 添加商品→hset cart1 100 1
  2. 增加数量→hincrby cart1 100 1(减少数量用负数)
  3. 商品总数→hlen cart1
  4. 删除商品→hdel cart1 10l0
  5. 获取购物车所有商品→hgetall cart1
3、list列表(可以重复)

列表是简单的字符串列表,可以存储重复元素,可以控制添加的位置。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

  • lpush key value[value...]:添加元素到表头(最左边)
  • rpush key value[value...]:添加元素到表尾(最右边)  redis_第21张图片
  • lpop key:移除并返回列表的头元素
  • rpop key:移除并返回列表的尾元素
  • lrange key start stop:返回列表key中指定区间内的元素,区间以偏移量start和stop

可以使用list实现队列和栈结构

Stack= LPUSH + LPOP =FILO

Queue= LPUSH + RPOP

redis_第22张图片

4、Set(无序、不重复集合)

sadd key member[member...]:往集合key中存入元素,元素存在则忽略,若key不存在则新建

srem key member[member...]:从集合key中删除元素

smembers key:获取集合key中所有元素

scard key:获取集合key的元素个数

redis_第23张图片

5、Zset(有序、不重复集合)

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。 zset 的成员是唯一的,但分数(score)却可以重复。

redis_第24张图片

  • zadd key score member[[score member]..]:往有序集合key中加入带分值元素  

redis_第25张图片 

  • zrem key member[member...]:从有序集合key中删除元素
  • zscore key member:返回有序集合key中元素member的分值
  • zincrby key increment member:为有序集合key中元素member的分值加上increment
  • zcard key:返回有序集合key中元素个数
  • zrange key start stop[withscores]:正序获取有序集合key,start下标到stop下标的元素

 redis_第26张图片

使用场景:记录微信朋友圈记录点赞用户

设置key的有效时间

有时候我们并不希望redis的key一直存在。例如缓存、验证码等数据,希望它们能在一定时间内自动的被销毁。设置key时,为key设置有效时间,时间到期后自动销毁。

1、设置值时直接设置有效时间

EX以秒为单位,PX以毫秒为单位。EX、PX不区分大小写

  • set key value ex 时间
  • set key value px 时间
  • ttl key:查看key的剩余时间(秒)
  • pttl key:查看key的剩余时间(毫秒)

redis_第27张图片 

2、设置值后设置有效时间
  • expire key 时间(秒)

  • pexpire key 时间(毫秒)

springboot集成连接redis

Jedis是redis官方提供的java连接redis数据库的实现类,里面封装很多的操作的方法。

Jedis  jedis = new Jedis("127.0.0.1", 6379);
jedis.set("name", "jim");
jedis.get("name");
jedis.incr("age");
jedis.hget("users", "1:name");	

直接以spring集成的redis为例来演示,spring中封装后提供了一个叫RedisTemplate的类,对redis的各种操作进行了封装。

通过springboot程序连接到阿里云服务器上的Redis数据库

1.导入jar


    org.springframework.boot
    spring-boot-starter-data-redis

 2.application.yml中,配置连接Redis

spring:
  #配置数据库的链接库信息,生成默认的数据源对象,并生成jdbcTemplate,事务管理功能都会进行初始化
  redis:
    host: 47.110.156.153
    port: 6379
    password: zh2873501408
    database: 0
    pool:
      max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
      max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
      max-idle: 8 # 连接池中的最大空闲连接
      min-idle: 0 # 连接池中的最小空闲连接
      timeout: 5000ms # 连接超时时间(毫秒)

3.注入RedisTemplate,并测试  

package com.ffyc.news;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

@SpringBootTest
class NewsApplicationTests {
	@Autowired
	RedisTemplate redisTemplate;

	@Test
	void contextLoads() {
		/*RedisTemplate中可以用来获取关于每种数据类型进行操作的访问接口
		ValueOperations redisTemplate.opsForValue(); 操作字符串类型的接口*/
		ValueOperations valueOperations= redisTemplate.opsForValue();
		valueOperations.set("a","aaa");
        
        //HashOperations hashOperations= redisTemplate.opsForHash();
		//hashOperations.put("users","1:name","jim");
	}
}

判断key是否存在hasKey(),删除key delete(),在RedisTemplate中封装的

package com.ffyc.news;

@SpringBootTest
class NewsApplicationTests {
	@Autowired
	RedisTemplate redisTemplate;

	@Test
	void contextLoads() {

		/*RedisTemplate中可以用来获取关于每种数据类型进行操作的访问接口
		 redisTemplate.opsForValue(); 操作字符串类型的接口*/
		ValueOperations valueOperations= redisTemplate.opsForValue();
		valueOperations.set("a","aaa");
		System.out.println(valueOperations.get("a"));//aaa,获取key
		System.out.println(redisTemplate.delete("a"));//true,全局的,删除key
		System.out.println(redisTemplate.hasKey("admin"));//false,全局的,判断key是否存在
	}
}

redis_第28张图片

对String类型的key、value进行序列化  

package com.ffyc.news;

@SpringBootTest
class NewsApplicationTests {
	@Autowired
	RedisTemplate redisTemplate;

	@Test
	void contextLoads() {

		//对String类型的key、value进行序列化
		redisTemplate.setKeySerializer(new StringRedisSerializer());
		redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(Object.class));

		ValueOperations valueOperations= redisTemplate.opsForValue();
		valueOperations.set("num",0);
		valueOperations.increment("num");//1
		valueOperations.increment("num");//2
		System.out.println(valueOperations.get("num"));//2

		User user=new User(1,"jim");
		valueOperations.set("user",user);
	}
} 
  

redis_第29张图片

redis_第30张图片

加上RedisConfig类,就不需要在每一个类中设置键值的序列化方式  

package com.ffyc.news.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    /**
     * 序列化键,值
     * @param connectionFactory
     * @return
     */
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        StringRedisSerializer redisSerializer = new StringRedisSerializer();

        redisTemplate.setKeySerializer(redisSerializer);//设置string类型的key,序列化方式是String
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);//设置string类型的值,序列化方式为json

        //redisTemplate.setHashKeySerializer(redisSerializer);
        //redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        return redisTemplate;
    }
} 
  

设置有效期

package com.ffyc.news;

@SpringBootTest
class NewsApplicationTests {
	@Autowired
	RedisTemplate redisTemplate;

	@Test
	void contextLoads() {
		ValueOperations valueOperations= redisTemplate.opsForValue();
		//设置key时,并设置有效时间
		valueOperations.set("b","abc",20, TimeUnit.SECONDS);
	}
}

你可能感兴趣的:(redis,数据库,缓存)