分布式文件存储与数据缓存 Redis高可用分布式实践(下)(一)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 Redis 版,标准版 2GB
推荐场景:
搭建游戏排行榜
云原生内存数据库 Tair,内存型 2GB
简介: 分布式文件存储与数据缓存 Redis高可用分布式实践(下)(一)

六、Redisweb实践 网页缓存

 

1.创建springboot项目

2.选择组件

Lombok

spring mvc

spring data redis

spring data jpa

3.编写配置文件

### 数据库访问配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.66.100:3307/test?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
########################################################
### Java Persistence Api --y
########################################################
# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
#[org.hibernate.cfg.ImprovedNamingStrategy  #org.hibernate.cfg.DefaultNamingStrategy]
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# stripped before adding them to the entity manager)
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
########################################################
### 配置连接池数据库访问配置
########################################################
#Redis服务器连接地址
spring.redis.host=192.168.66.100
#Redis服务器连接端口
spring.redis.port=6379
#连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
#连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.pool.max-idle=8
#连接池中的最小空闲连接
spring.redis.pool.min-idle=0
#连接超时时间(毫秒)
spring.redis.timeout=30000
logging.pattern.console=%d{MM/dd HH:mm:ss.SSS} %clr(%-5level) ---  [%-15thread] %cyan(%-50logger{50}):%msg%n

4.创建实体类

package com.zj.redis.pojo;
import lombok.Data;
import javax.persistence.*;
@Data
@Entity
@Table(name = "goods")
public class GoodsEntity {
   //自增ID
   @Id
   @GeneratedValue(strategy= GenerationType.IDENTITY)//自增
   private Long id;
   // 商品名字
   private String goodsName;
   // 订单id
   private String orderId;
   // 商品数量
   private Integer goodsNum;
   // 商品价格
   private Double price;
}

5.编写持久层

package com.zj.redis.mapper;
import com.zj.redis.pojo.GoodsEntity;
import org.springframework.data.jpa.repository.JpaRepository;
/*
   GoodsEntity:表示的是实体类
   Long:表示的是实体的主键的类型
 */
public interface GoodsMapper extends JpaRepository<GoodsEntity,Long> {
}

6.编写业务层

package com.zj.redis.service;
import com.zj.redis.mapper.GoodsMapper;
import com.zj.redis.pojo.GoodsEntity;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Optional;
@Service
public class GoodsService {
    @Resource
    private GoodsMapper goodsMapper;
    //根据商品的id查询商品的信息
    public GoodsEntity selectById(Long id) {
        Optional<GoodsEntity> goodsEntity  = goodsMapper.findById(id);
        if ( goodsEntity.isPresent()){
            return goodsEntity.get();
        }
        return null;
    }
}

7.编写控制层

package com.zj.redis.controller;
import com.zj.redis.pojo.GoodsEntity;
import com.zj.redis.service.GoodsService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class GoodsController {
    @Resource
    private GoodsService goodsService;
    //根据id查询商品
    @GetMapping("/goods")
    public GoodsEntity findById(String id) {
      return goodsService.selectById(Long.valueOf(id));
    }
}

8.启动mysql的docker容器

#查看全部docker容器
[root@localhost /]# docker ps -a
#启动MySQL容器
[root@localhost /]# docker start 43f

9.navicat连接mysql容器

10.运行项目

数据库出现该表表示项目搭建成功!

11.浏览器请求

12.下载压测工具Jmeter并启动

13.修改语言

14.创建压测

添加线程组

15.添加HTTP请求

16.添加压测结果报告

没有加缓存的吞吐量:

17.添加redis缓存

package com.zj.redis.service;
import com.alibaba.fastjson.JSON;
import com.zj.redis.mapper.GoodsMapper;
import com.zj.redis.pojo.GoodsEntity;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
@Service
public class GoodsService {
    @Resource
    private GoodsMapper goodsMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    //根据商品的id查询商品的信息
    public GoodsEntity selectById(Long id) {
        String goodString = stringRedisTemplate.opsForValue().get("good:" + id);
        //判断有没有缓存
        if (StringUtils.isEmpty(goodString)) {
            //从数据库查询信息
            GoodsEntity goodsEntity = goodsMapper.findById(Long.valueOf(id)).get();
            //将对象转为json格式
            String goodsEntityJson = JSON.toJSONString(goodsEntity);
            //添加到redis缓存
            stringRedisTemplate.opsForValue().set("good:" + id, goodsEntityJson);
            return goodsEntity;
        }else {
            //字符串转为对象类型
            GoodsEntity goodsEntity = JSON.parseObject(goodString, GoodsEntity.class);
            return goodsEntity;
        }
    }
}

开启redis:

[root@localhost src]# ./redis-server ../redis.conf

启动项目,访问

发现缓存中出现good。

18.继续压力测试

添加缓存后的吞吐量达到8400多。

总结:10000并发在不添加缓存的吞吐量是1062,在添加缓存后的吞吐量是8496.

七、Redis配置文件详解

在Redis的解压目录下有个很重要的配置文件 redis.conf ,关于Redis的很多功能的配置都在此文件中完成的,一般为了不破坏安装的文件,出厂默认配置最好不要去改。

units单位

配置大小单位,开头定义基本度量单位,只支持bytes,大小写不敏感。

INCLUDES

Redis只有一个配置文件,如果多个人进行开发维护,那么就需要多个这样的配置文件,这时候多个配置文件就可以在此通过 include /path/to/local.conf 配置进来,而原本的 redis.conf 配置文件就作为一个总闸。

NETWORK

参数:

  • bind:绑定redis服务器网卡IP,默认为127.0.0.1,即本地回环地址。这样的话,访问redis服务只能通过本机的客户端连接,而无法通过远程连接。如果bind选项为空的话,那会接受所有来自于可用网络接口的连接。
  • port:指定redis运行的端口,默认是6379。由于Redis是单线程模型,因此单机开多个Redis进程的时候会修改端口。
  • timeout:设置客户端连接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该连接。默认值为0,表示不关闭。
  • tcp-keepalive :单位是秒,表示将周期性的使用SO_KEEPALIVE检测客户端是否还处于健康状态,避免服务器一直阻塞,官方给出的建议值是300s,如果设置为0,则不会周期性的检测。

GENERAL

具体配置详解:

  • daemonize:设置为yes表示指定Redis以守护进程的方式启动(后台启动)。默认值为 no
  • pidfile:配置PID文件路径,当redis作为守护进程运行的时候,它会把 pid 默认写到 /var/redis/run/redis_6379.pid 文件里面
  • loglevel :定义日志级别。默认值为notice,有如下4种取值:

debug(记录大量日志信息,适用于开发、测试阶段)

verbose(较多日志信息)

notice(适量日志信息,使用于生产环境)

warning(仅有部分重要、关键信息才会被记录)

  • logfile :配置log文件地址,默认打印在命令行终端的窗口上
  • databases:设置数据库的数目。默认的数据库是DB 0 ,可以在每个连接上使用select 命令选择一个不同的数据库,dbid是一个介于0到databases - 1 之间的数值。默认值是 16,也就是说默认Redis有16个数据库。

SNAPSHOTTING

这里的配置主要用来做持久化操作。

参数:

save:这里是用来配置触发 Redis的持久化条件,也就是什么时候将内存中的数据保存到硬盘

save 900 1:表示900 秒内如果至少有 1 个 key 的值变化,则保存 save 300 10:表示300 秒内如果至少有 10 个 key 的值变化,则保存 save 60 10000:表示60 秒内如果至少有 10000 个 key 的值变化,则保存

REPLICATION

参数:

  • slave-serve-stale-data:默认值为yes。当一个 slave 与 master 失去联系,或者复制正在进行的时候,

slave 可能会有两种表现:

  1. 如果为 yes ,slave 仍然会应答客户端请求,但返回的数据可能是过时,或者数据可能是空的在第一次同步的时候
  1. 如果为 no ,在你执行除了 info he salveof 之外的其他命令时,slave 都将返回一个 "SYNC with master in progress" 的错误
  • slave-read-only:配置Redis的Slave实例是否接受写操作,即Slave是否为只读Redis。默认值为yes。
  • repl-diskless-sync:主从数据复制是否使用无硬盘复制功能。默认值为no。
  • repl-diskless-sync-delay:当启用无硬盘备份,服务器等待一段时间后才会通过套接字向从站传送RDB文件,这个等待时间是可配置的。
  • repl-disable-tcp-nodelay:同步之后是否禁用从站上的TCP_NODELAY 如果你选择yes,redis会使用较少量的TCP包和带宽向从站发送数据。

SECURITY

requirepass:设置redis连接密码。

比如: requirepass 123 表示redis的连接密码为123。

CLIENTS

参数:

maxclients :设置客户端最大并发连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件。 描述符数-32(redis server自身会使用一些),如果设置 maxclients为0 。表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息

MEMORY MANAGEMENT

参数:

  • maxmemory:设置Redis的最大内存,如果设置为0 。表示不作限制。通常是配合下面介绍的maxmemory-policy参数一起使用。
  • maxmemory-policy :当内存使用达到maxmemory设置的最大值时,redis使用的内存清除策略。有以下几种可以选择:

    1)volatile-lru 利用LRU算法移除设置过过期时间的key (LRU:最近使用 Least Recently Used )

    2)allkeys-lru 利用LRU算法移除任何key

    3)volatile-random 移除设置过过期时间的随机key

    4)allkeys-random 移除随机ke

    5)volatile-ttl 移除即将过期的key(minor TTL)

    6)noeviction noeviction 不移除任何key,只是返回一个写错误 ,默认选项

  • maxmemory-samples :LRU 和 minimal TTL 算法都不是精准的算法,但是相对精确的算法(为了节省内存)。随意你可以选择样本大小进行检,redis默认选择3个样本进行检测,你可以通过maxmemory-samples进行设置样本数。

APPEND ONLY MODE

参数:

  • appendonly:默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了。但是redis如果中途宕机,会导致可能有几分钟的数据丢失,根据save来策略进行持久化,Append Only File是另一种持久化方式, 可以提供更好的持久化特性。Redis会把每次写入的数据在接收后都写入appendonly.aof文件,每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。默认值为no。
  • appendfilename :aof文件名,默认是"appendonly.aof"
  • appendfsync:aof持久化策略的配置;no表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快;always表示每次写入都执行fsync,以保证数据同步到磁盘;everysec表示每秒执行一次fsync,可能会导致丢失这1s数据

LUA SCRIPTING

参数:

lua-time-limit:一个lua脚本执行的最大时间,单位为ms。默认值为5000.

REDIS CLUSTER

参数:

  • cluster-enabled:集群开关,默认是不开启集群模式。
  • cluster-config-file:集群配置文件的名称。
  • cluster-node-timeout :可以配置值为15000。节点互连超时的阀值,集群节点超时毫秒数
  • cluster-slave-validity-factor :可以配置值为10。


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
6天前
|
canal 缓存 NoSQL
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
根据对一致性的要求程度,提出多种解决方案:同步删除、同步删除+可靠消息、延时双删、异步监听+可靠消息、多重保障方案
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
|
7天前
|
存储 NoSQL Redis
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
Redis持久化、RDB和AOF方案、Redis主从集群、哨兵、分片集群、散列插槽、自动手动故障转移
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
|
17天前
|
缓存 NoSQL 关系型数据库
MySQL与Redis缓存一致性的实现与挑战
在现代软件开发中,MySQL作为关系型数据库管理系统,广泛应用于数据存储;而Redis则以其高性能的内存数据结构存储特性,常被用作缓存层来提升数据访问速度。然而,当MySQL与Redis结合使用时,确保两者之间的数据一致性成为了一个重要且复杂的挑战。本文将从技术角度分享MySQL与Redis缓存一致性的实现方法及其面临的挑战。
42 2
|
机器学习/深度学习 缓存 NoSQL
|
缓存 NoSQL Java
为什么分布式一定要有redis?
1、为什么使用redis 分析:博主觉得在项目中使用redis,主要是从两个角度去考虑:性能和并发。当然,redis还具备可以做分布式锁等其他功能,但是如果只是为了分布式锁这些其他功能,完全还有其他中间件(如zookpeer等)代替,并不是非要使用redis。
1356 0
|
26天前
|
缓存 NoSQL 网络安全
【Azure Redis 缓存】Azure Redis服务开启了SSL(6380端口), PHP如何访问缓存呢?
【Azure Redis 缓存】Azure Redis服务开启了SSL(6380端口), PHP如何访问缓存呢?
|
26天前
|
缓存 NoSQL Redis
【Azure Redis 缓存】Redission客户端连接Azure:客户端出现 Unable to send PING command over channel
【Azure Redis 缓存】Redission客户端连接Azure:客户端出现 Unable to send PING command over channel
|
26天前
|
缓存 NoSQL 网络协议
【Azure Redis 缓存】Lettuce 连接到Azure Redis服务,出现15分钟Timeout问题
【Azure Redis 缓存】Lettuce 连接到Azure Redis服务,出现15分钟Timeout问题
【Azure Redis 缓存】Lettuce 连接到Azure Redis服务,出现15分钟Timeout问题
|
22天前
|
缓存 NoSQL Java
Redis深度解析:解锁高性能缓存的终极武器,让你的应用飞起来
【8月更文挑战第29天】本文从基本概念入手,通过实战示例、原理解析和高级使用技巧,全面讲解Redis这一高性能键值对数据库。Redis基于内存存储,支持多种数据结构,如字符串、列表和哈希表等,常用于数据库、缓存及消息队列。文中详细介绍了如何在Spring Boot项目中集成Redis,并展示了其工作原理、缓存实现方法及高级特性,如事务、发布/订阅、Lua脚本和集群等,帮助读者从入门到精通Redis,大幅提升应用性能与可扩展性。
49 0
|
26天前
|
缓存 NoSQL Redis
【Azure Redis 缓存】使用StackExchange.Redis,偶发ERROR - Timeout performing HSET (15000ms)
【Azure Redis 缓存】使用StackExchange.Redis,偶发ERROR - Timeout performing HSET (15000ms)