首页
友链
关于
免责声明
Search
1
王者营地战绩数据王者荣耀查询网页源码
6,209 阅读
2
群晖Active Backup for Business套件备份Linux服务器教程
4,384 阅读
3
影视分享
4,313 阅读
4
(亲测)Jrebel激活破解方式2019-08-21
4,289 阅读
5
centos7 安装及卸载 jekenis
3,573 阅读
日常
文章
后端
前端
Linux
异常
Flutter
分享
群辉
登录
Search
标签搜索
docker
springboot
Spring Boot
java
linux
Shiro
Graphics2D
图片
游戏账号交易
Mybatis
Spring Cloud
centos
脚本
Web Station
群辉
王者营地
战绩查询
平台对接
Spring Cloud Alibaba
nacos
绿林寻猫
累计撰写
249
篇文章
累计收到
26
条评论
首页
栏目
日常
文章
后端
前端
Linux
异常
Flutter
分享
群辉
页面
友链
关于
免责声明
搜索到
52
篇与
Linux
的结果
2021-12-08
Linux服务器执行sql文件
首先打开对应的databaseuse 数据库名;执行文件source /usr/文件名.sql -- 直接回车查看所有表show tables;
2021年12月08日
174 阅读
0 评论
0 点赞
2021-12-08
Linux解决mysql数据库区分大小写的问题
打开/etc/my.cnf 或 /etc/myql/my.cnf添加lower_case_table_names=1,表示mysql不区分大小写,这段代码必须在[mysqld_safe]之前 重启MySQL服务service mysqld restart 设置成功,则不再区分表名的大小写。
2021年12月08日
141 阅读
0 评论
0 点赞
2021-12-08
linux一个tomcat配置多个项目,直接端口访问
一、修改tomcat的conf目录下的server.xml配置service 节点,有几个项目就相应的配置几个service 节点;注意修改Service name; Connector port; Engine name; Host appBase<?xml version='1.0' encoding='utf-8'?> <Server port="8054" shutdown="SHUTDOWN"> <!-- Security listener. Documentation at /docs/config/listeners.html <Listener className="org.apache.catalina.security.SecurityListener" /> --> <!--APR library loader. Documentation at /docs/apr.html --> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html --> <Listener className="org.apache.catalina.core.JasperListener" /> <!-- Prevent memory leaks due to use of particular java/javax APIs--> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> <GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> <Service name="Catalina1"> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="9543" /> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina1" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="webapps1" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> <Context path="" reloadable="true" docBase="项目文件夹"/> </Host> </Engine> </Service> <Service name="Catalina2"> <!--把port改成8081--> <Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="9543" /> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina2" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="webapps2" ---这里要修改为修改后的webapps名称 unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> <Context path="" reloadable="true" docBase="项目文件夹"/> </Host> </Engine> </Service> </Server>二、先依照此配置文件配置,完成后在tomcat根目录下复制文件夹webapps,粘贴重命名为webapps1,webapps2,如下图:此文件夹就是分别用来部署项目的。三、在tomcat根目录下的conf文件中,复制conf文件夹下的Catalina文件夹,粘贴并重命名为Catalina1,Catalina2,如图:配置完成,现在可以把项目分别部署到配置好的两个文件夹webapps1和webapps2中;启动tomcat,分别用不同的端口号8080和8081测试;http://ip:8080http://ip:8081注:如果第一次重启tomcat访问的是tomcat页面,再重启一次就好了
2021年12月08日
209 阅读
0 评论
0 点赞
2021-12-08
linux查看tomcat启动信息
1、首先启动tomcat2、找到tomcat安装目录:cd tomcat/logs3、运行 tail -f catalina.out就可以看到本地软件启动项目是显示的日志4、ctrl+c 退出
2021年12月08日
222 阅读
0 评论
0 点赞
2021-12-08
Redis离线安装与在线安装
离线安装Redis官网下载Redis压缩包下载地址:http://redis.io/download,下载最新文档版本。 通过WinSCP等远程管理工具,将压缩包复制到Linux服务器这里在Linux中创建目录:/redis,并将压缩包复制到该目录: $ mkdir /redis 解压压缩文件,并执行make对解压后的文件进行编译在Linux中通过命令方式下载并安装: $ cd /redis# 将redis解压到/dml/redis目录$ tar -zxvf redis-4.0.11.tar.gz$ cd redis-4.0.11# 编译$ make 解压:查看解压后的目录:进入解压目录查看:编译:编译时出现gcc错误:安装gcc依赖: $ yum install gcc 再次编译安装: $ make MALLOC=libc 编译完后,可以看到解压文件redis中会对应的src、conf等文件夹。直接启动Redis进入src文件夹,查看目录,找到redis-server服务:直接启动Redis服务: $ ./redis-server 出现如下界面表示已启动 redis服务:在线安装Redis在CentOS系统在线安装 Redis 可以使用以下命令获得最近的软件包的列表: $ sudo yum update 安装Redis服务端: $ sudo yum install redis-server 启动 Redis服务: $ ./redis-server 以后台进程方式启动Redis第一步:修改redis.conf文件 $ vim redis.conf 将:daemoize no改为daemoize yes,保存并退出。文档中:databases 16表示Redis中默认的数据库有16个,但没有名字。 第二步:在src下 指定redis.conf文件启动 $ ./redis-server /redis/redis-4.0.11/redis.conf redis.conf是一个默认的配置文件。我们可以根据需要使用自己的配置文件。 启动Redis客户端在成功启动Redis服务后,即可启动客启端。注意:这里最好再开一个终端测试。进入Redis-4.0.11/src目录,启动Redis客户端: $ ./redis-cli 以上命令将打开以下终端: 127.0.0.1:6379> 127.0.0.1 是本机 IP ,6379 是Redis服务端口。现在我们输入PING命令,测试是否连接成功。 127.0.0.1:6379> ping 如果现面 PONG 表示连接成功。 关闭Redis第一步:查看redis进程 $ ps -aux | grep redis 第二步:杀死进程 $ kill -9 1693
2021年12月08日
108 阅读
0 评论
0 点赞
2021-12-08
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect ti
redis连接报错:redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out开启防火墙(systemctl start firewalld)1.使用命令 firewall-cmd --state查看防火墙状态。得到结果是running或者not running2.在running 状态下,向firewall 添加需要开放的端口命令为 firewall-cmd --permanent --zone=public --add-port=6379/tcp //永久的添加该端口。去掉--permanent则表示临时。4.firewall-cmd --reload //加载配置,使得修改有效。5.使用命令 firewall-cmd --permanent --zone=public --list-ports //查看开启的端口,出现6379/tcp这开启正确 在redis客户端输入:config set protected-mode "no"再测试:@Test public void test(){ Jedis jedis = new Jedis("192.168.***.***" , 6379); jedis.set("key2", "aaaaaa"); String key2 = jedis.get("key2"); System.out.println("获取到的key2为:"+key2); jedis.close(); }
2021年12月08日
167 阅读
0 评论
0 点赞
2021-12-08
redis配置 分布式锁及string、list、hash、set、zset基本操作
配置:spring: redis: host: 127.0.0.1 port: 6379 password: jedis: pool: max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。 max-idle: 100 #最大等待连接中的数量,设 0 为没有限制 max-active: 300 #最大连接数据库连接数,设 0 为没有限制 min-idle: 10 #最小等待连接数<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>操作:package com.demo.util; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Component; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.TimeUnit; @Component public class RedisUtil { @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired private RedisTemplate redisTemplate; //解锁时间 public static final int LOCK_EXPIRE = 1000; // ms /** * 读取缓存 * * @param key * @return */ public Object get(final String key) { return redisTemplate.opsForValue().get(key); } /** * 写入缓存 */ public boolean set(final String key, Object value) { boolean result = false; try { redisTemplate.opsForValue().set(key, value); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } /** * 写入缓存 自定义有效时间 * TimeUnit是java.util.concurrent包下面的一个类,表示给定单元粒度的时间段 * 主要作用 * 时间颗粒度转换 * 延时 * * TimeUnit.DAYS //天 * TimeUnit.HOURS //小时 * TimeUnit.MINUTES //分钟 * TimeUnit.SECONDS //秒 * TimeUnit.MILLISECONDS //毫秒 */ public boolean set(final String key, Object value,Long timeout) { boolean result = false; try { redisTemplate.opsForValue().set(key, value,timeout, TimeUnit.SECONDS); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } /** * 更新缓存 */ public boolean getAndSet(final String key, Object value) { boolean result = false; try { redisTemplate.opsForValue().getAndSet(key, value); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } /** * 删除缓存 */ public boolean delete(final String key) { boolean result = false; try { redisTemplate.delete(key); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } /** * 分布式锁 * * @param key key值 * @param lockPrefix 锁的前缀 * @return 是否获取到 */ public boolean lock(String key,String lockPrefix){ String lock = lockPrefix + key; // lambda表达式 return (Boolean) redisTemplate.execute((RedisCallback) connection -> { long expireAt = System.currentTimeMillis() + LOCK_EXPIRE + 1; Boolean acquire = connection.setNX(lock.getBytes(), String.valueOf(expireAt).getBytes()); if (acquire) { return true; } else { byte[] value = connection.get(lock.getBytes()); if (Objects.nonNull(value) && value.length > 0) { long expireTime = Long.parseLong(new String(value)); if (expireTime < System.currentTimeMillis()) { // 如果锁已经过期 byte[] oldValue = connection.getSet(lock.getBytes(), String.valueOf(System.currentTimeMillis() + LOCK_EXPIRE + 1).getBytes()); // 防止死锁 return Long.parseLong(new String(oldValue)) < System.currentTimeMillis(); } } } return false; }); } /** * 解锁 * * @param key */ public void unlock(String key,String lockPrefix) { redisTemplate.delete(lockPrefix+key); } /** * 例子 * boolean lock = lock("123", "LOCK"); if (lock) { unlock("123", "LOCK"); } else { // 设置失败次数计数器, 当到达5次时, 返回失败 int failCount = 1; while (failCount <= 5) { // 等待100ms重试 try { Thread.sleep(100L); } catch (InterruptedException e) { e.printStackTrace(); } if (lock("123", "LOCK")) { unlock("123", "LOCK"); } else { failCount++; } } }*/ //STRING---------------- /** * String * @param key * @param value * @param expirationTime */ public void setString(String key, String value,long expirationTime) { //SECONDS 秒 MINUTES 分钟 HOURS 小时 this.stringRedisTemplate.opsForValue().set(key, value,expirationTime, TimeUnit.SECONDS); } /** * * @param key * @return String */ public String getStringByKey(String key) { return this.stringRedisTemplate.opsForValue().get(key); } /** * * @param key */ public Boolean deleteStringByKey(String key) { return this.stringRedisTemplate.delete(key); } // LIST ------------------------------------- /** * 示例: * 起始数据: 1 2 3 * 添加: 4 * 结果: 4 1 2 3 * @param key * @param value */ public Long setListLeft(String key,String value){ return this.stringRedisTemplate.opsForList().leftPush(key, value); } /** * 示例: * 起始数据: 1 2 3 * 添加: 4 * 结果: 1 2 3 4 * @param key * @param value */ public Long setListRight(String key,String value){ return this.stringRedisTemplate.opsForList().rightPush(key,value); } /** * * @param key * @param i 起始下标(包含) * @param n 结束下标 (包含) (查询全部结束下标为-1) * @return */ public List<String> getList(String key,int i,int n){ return stringRedisTemplate.opsForList().range( key, i, n); } /** * 示例: * 删除先进入的B元素(如果含有多个B元素,删除最左边的) * stringRedisTemplate.opsForList().remove("redlist",1, "B");//["0","1","2","A"] * 删除所有A元素 * stringRedisTemplate.opsForList().remove("redlist",0, "A");//["0","1","2"] * @param key * @param i * @param str * @return */ public Long deleteByListKey(String key,int i,String str){ return stringRedisTemplate.opsForList().remove(key, i, str); } //HASH -------------------------------- /** * * @param rKey redis键 * @param mKey map键 * @param mValue map值 */ public void setHash(String rKey,String mKey,String mValue){ stringRedisTemplate.opsForHash().put(rKey,mKey,mValue); } /** * 获取map对象 * 示例:{"a":"d","b":"d"} * @param rKey redis键 * @return */ public Map<Object, Object> getHashMap(String rKey){ return stringRedisTemplate.opsForHash().entries(rKey); } /** * 获取map的key * 示例:["a","b"] * @param rKey redis键 * @return */ public Set<Object> getHashMapKey(String rKey){ return stringRedisTemplate.opsForHash().keys(rKey); } /** * 获取map的key * 示例:["d","d"] * @param rKey redis键 * @return */ public List<Object> getHashMapValue(String rKey){ return stringRedisTemplate.opsForHash().values(rKey); } /** * 获取map大小 * @param rKey redis键 * @return */ public long getHashMapSize(String rKey){ return stringRedisTemplate.opsForHash().size(rKey); } /** * * @param rKey redis键 * @param mKey map键一个或多个(当删除完所有的key时,该map对象注销) */ public Long deleteHashMapByKey(String rKey,String... mKey ){ return stringRedisTemplate.opsForHash().delete(rKey, mKey); } //SET ================== /** * * @param key redis键 * @param value 一个或多个 * @return */ public Long setSet(String key ,String... value){ return stringRedisTemplate.opsForSet().add(key,value); } /** * * @param key redis键 * @return */ public Set<String> getSet(String key){ return stringRedisTemplate.opsForSet().members(key); } /** * 判断值是否存在set集合中 * @param key redis键 * @param value set集合里的值 * @return */ public Boolean isMember(String key,String value){ return stringRedisTemplate.opsForSet().isMember(key,value); } /** * * @param key redis键 * @param value set集合里的值(当值都清空时,key注销) * @return */ public Long deleteSet(String key,String... value){ return stringRedisTemplate.opsForSet().remove(key,value); } //ZSET================================ /** * 向指定集合zset中添加元素value,score用于排序,如果该元素已经存在,则更新其顺序 * @param key * @param value * @param d * @return */ public Boolean setZSet(String key,String value,Double d){ return stringRedisTemplate.opsForZSet().add(key, value, d); } /** * value在集合中时,返回其score;如果不在,则返回null * @param key * @param value * @return */ public Double getScore(String key, String value) { return stringRedisTemplate.opsForZSet().score(key, value); } /** * 查询集合中指定顺序的值, 0 -1 表示获取全部的集合内容 zrange * * 返回有序的集合,score小的在前面 * * @param key * @param start * @param end * @return */ public Set<String> range(String key, int start, int end) { return stringRedisTemplate.opsForZSet().range(key, start, end); } /** * 查询集合中指定顺序的值和score,0, -1 表示获取全部的集合内容 * * @param key * @param start * @param end * @return */ public Set<ZSetOperations.TypedTuple<String>> rangeWithScore(String key, int start, int end) { return stringRedisTemplate.opsForZSet().rangeWithScores(key, start, end); } /** * 查询集合中指定顺序的值 zrevrange * * 返回有序的集合中,score大的在前面 * * @param key * @param start * @param end * @return */ public Set<String> revRange(String key, int start, int end) { return stringRedisTemplate.opsForZSet().reverseRange(key, start, end); } /** * 根据score的值,来获取满足条件的集合 zrangebyscore * * @param key * @param min * @param max * @return */ public Set<String> sortRange(String key, int min, int max) { return stringRedisTemplate.opsForZSet().rangeByScore(key, min, max); } /** * zset中的元素塞入之后,可以修改其score的值, * 当元素不存在时,则会新插入一个 * @param key * @param value * @param score * @return */ public Double incrScore(String key, String value, double score) { return stringRedisTemplate.opsForZSet().incrementScore(key, value, score); } /** * 判断value在zset中的排名 * * @param key * @param value * @return */ public Long rank(String key, String value) { return stringRedisTemplate.opsForZSet().rank(key, value); } /** * 返回集合的长度 * * @param key * @return */ public Long size(String key) { return stringRedisTemplate.opsForZSet().zCard(key); } } package com.demo.dto; import java.io.Serializable; /** * @Author: LiuYong * @Date:2020/04/26 9:57 * @Description: TODO 描述 */ public class UserDto implements Serializable { private static final long serialVersionUID = -5255173691529786212L; private String userId; private String userName; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } @Override public String toString() { return "UserDto{" + "userId=" + userId + ", userName='" + userName + '\'' + '}'; } } package com.demo; import com.demo.dto.UserDto; import com.demo.util.RedisUtil; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class DemoApplicationTests { @Autowired private RedisUtil redisUtil; @Test void contextLoads() { UserDto userDto = new UserDto(); userDto.setUserName("张三"); userDto.setUserId("1"); boolean user = redisUtil.set("user", userDto); System.out.println(user); UserDto user1 = (UserDto)redisUtil.get("user"); System.out.println(user1); } } 附:redis Windows工具https://www.electronjs.org/apps/anotherredisdesktopmanager
2021年12月08日
186 阅读
0 评论
0 点赞
2021-12-08
Redis 介绍及各类策略、问题解决
目录 一、Redis介绍 1.1数据类型 1.2优缺点 二、为什么要使用Redis/缓存?2.1高性能 2.2高并发三、持久化3.1什么是持久化?3.2持久化机制3.2.1Redis DataBase(简称RDB) 3.2.3Append-only file (简称AOF)四、Redis过期键的删除策略4.1常见删除策略五、Redis内存淘汰策略5.1全局的键空间选择性移除5.2设置过期时间的键空间选择性移除六、缓存异常6.1缓存雪崩6.2缓存穿透6.3缓存击穿一、Redis介绍简单来说Redis是一款高性能非关系型的键值对数据库。与传统数据库不同的是Redis的数据是存储在内存中,所以读写速度非常快。因此被广泛应用于缓存方面,每秒可处理超过10W次的读写操作,Redis也经常用来做分布式锁,此外,Redis支持事务、持久化、LUA脚本、LRU驱动事件、多集群方案。Redis可以存储键和五种不同类型的值之间的映射,键类型只能为字符串,支持五种数据类型:String、List、Set、ZSet、Hash。 1.1数据类型数据类型可以存储的值操作应用场景STRING字符串、整数或者浮点数对整个字符串或者字符串的其中一部分执行操作对整数和浮点数执行自增或者自减操作做简单的键值对缓存LIST列表从两端压入或者弹出元素对单个或者多个元素进行修剪,只保留一个范围内的元素存储一些列表型的数据结构,类似粉丝列表、文章的评论列表之类的数据SET无序集合添加、获取、移除单个元素检查一个元素是否存在于集合中计算交集、并集、差集从集合里面随机获取元素交集、并集、差集的操作,比如交集,可以把两个人的粉丝列表整一个交集HASH包含键值对的无序散列表添加、获取、移除单个键值对获取所有键值对检查某个键是否存在结构化的数据,比如一个对象ZSET有序集合添加、获取、删除元素根据分值范围或者成员来获取元素计算一个键的排名去重但可以排序,如获取排名前几名的用户 1.2优缺点优:读写速度快支持数据持久化,AOF和RDB两种方式支持事务数据结构丰富,除了支持string类型的value外还支持hash、set、zset、list等数据结构支持主从复制,主机会自动将数据同步到从机,可以进行读写分离缺:数据库受物理内存限制,不适合海量数据高性能读写,一般作用于小数据量的高性能操作和运算Redis不具备自动容错和恢复功能,主从机的宕机都有可能造成读写失败,需等待重启或前端手动更改IP才能恢复主机宕机前有部分数据未能同步到从机,切换IP后有可能造成数据不一致的问题,降低了系统可用性能Redis较难支持在线扩容,在集群容量达到上限后在线扩容会变得复杂,运维人员得在运行前确保有足够的容量 二、为什么要使用Redis/缓存? 2.1高性能如用户第一次获取数据时是从数据库获取,因数据是从硬盘上读取,相对缓慢一些。将此次请求数据存于缓存,再次访问数据时是从缓存中获取,是直接操作内存,速度相对会快很多。如果数据库中数据发生变化,则把相应Key缓存数据删除,下次获取数据又会和第一次获取数据一样,且确保数据是最新数据。 2.2高并发直接操作缓存请求远远大于直接请求数据库,以秒杀/抢红包为例,在活动开始前把数据存储在缓存中,活动结束后再同步redis数据到数据库。三、持久化 3.1什么是持久化?持久化就是将数据存储到磁盘,以防宕机数据丢失无法恢复。 3.2持久化机制 3.2.1Redis DataBase(简称RDB)执行机制:快照,直接将databases中的key-value的二进制形式存储在了rdb文件中优点:性能较高(因为是快照,且执行频率比aof低,而且rdb文件中直接存储的是key-values的二进制形式,对于恢复数据也快)使用单独子进程来进行持久化,主进程不会进行任何IO操作,保证了redis的高性能缺点:在save配置条件之间若发生宕机,此间的数据会丢失RDB是间隔一段时间进行持久化,如果持久化之间redis发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候 3.2.3Append-only file (简称AOF)执行机制:将对数据的每一条修改命令追加到aof文件优点:数据不容易丢失可以保持更高的数据完整性,如果设置追加file的时间是1s,如果redis发生故障,最多会丢失1s的数据;且如果日志写入不完整支持redis-check-aof来进行日志修复;AOF文件没被rewrite之前(文件过大时会对命令进行合并重写),可以删除其中的某些命令(比如误操作的flushall)缺点:性能较低(每一条修改操作都要追加到aof文件,执行频率较RDB要高,而且aof文件中存储的是命令,对于恢复数据来讲需要逐行执行命令,所以恢复慢)AOF文件比RDB文件大,且恢复速度慢。 四、Redis过期键的删除策略 4.1常见删除策略定时删除:每个设置过期时间的Key都会创建一个定时器,到期就会定时删除,该策略会立即删除过期数据,对内存很友好。但是相对的会占用大量的CPU资源去处理过期数据处理,从而会影响缓存响应时间及吞吐量。惰性删除:对CPU来说是最友好,只会在程序读取该数据时校验数据是否存在,不存在就删除。但是相对的对内存来说不友好,比如一些已经过去的数据,不去读取时永远不知道是否过期,更不会删除,这个键就一直存在,占用着内存资源。定期删除:就是前两种策略的整合和折中,每隔一段时间程序执行一次过期键删除操作,通过限制删除的频率和时长来减少删除操作对CPU的影响。有效的减少了过期键对内存资源的占用 五、Redis内存淘汰策略Redis内存淘汰策略是指在内存不足时,新数据怎么申请额外的空间数据。 5.1全局的键空间选择性移除noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。(这个是最常用的)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。 5.2设置过期时间的键空间选择性移除volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。 Redis的内存淘汰策略的选取并不会影响过期的key的处理。内存淘汰策略用于处理内存不足时的需要申请额外空间的数据;过期策略用于处理过期的缓存数据。 六、缓存异常 6.1缓存雪崩缓存雪崩是指缓存数据同一时间大面积过期,造成所有请求都访问数据库,因短时间请求压力过大从而造成数据库崩掉。解决方案:随机设置过期时间,避免同一时间过期并发量不是特别多的,最多处理方式是加锁排队给每个缓存数据添加标记,记录缓存是否失效,如果失效则更新缓存6.2缓存穿透缓存穿透是指数据库和缓存中都没有数据,造成所有请求都访问数据库,因短时间请求压力过大从而造成数据库崩掉。解决方案:接口增加校验,如用户ID<0的直接拦截从缓存获取不到数据,数据库也不存在该数据,则设置一个Key-Value,Value=null的缓存,缓存时间可以设置30S,这样可以防止重复用一个ID暴力攻击。采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力6.3缓存击穿缓存击穿是指没有获取到缓存数据(一般是缓存过期),由于并发用户量大,同时获取一条数据,没从缓存中获取的,请求全到数据库上,造成数据库压力过大。和缓存雪崩不同的是,缓存击穿是并发查询同一条数据,而缓存雪崩是大片数据过期,很多数据查不到都查询数据库。解决方案:热点数据永不过期添加互斥锁,对缓存查询加锁,如果KEY不存在,就加锁,然后查数据库入缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入数据库查询
2021年12月08日
238 阅读
0 评论
0 点赞
2021-12-08
spring cloud服务配置公网ip
eureka 配置eureka: instance: instance-id: aaa #服务示例名 ip-address: 123.123.123.123 #公网ip
2021年12月08日
132 阅读
0 评论
0 点赞
2021-12-08
Spring Boot 整合之Redis
在添加 redis 依赖包启动项目后,Spring Boot 会自动配置 RedisCacheManger 和 RedisTemplate 的 Bean。如果开发者不想使用 Spring Boot 写好的 Redis 缓存,而是想使用其 API 自己实现缓存功能、消息队列或分布式锁之类的需求时,可以继续往下浏览。Spring Data Redis 为我们提供 RedisTemplate 和 StringRedisTemplate 两个模板进行数据操作,它们主要 的访问方法如下:方法说明opsForValue()操作简单属性的数据opsForList()操作含有 list 的数据opsForSet()操作含有 set 的数据opsForZSet()操作含有 zset 的数据opsForHash()操作含有 hash 的数据1.导入依赖 <!--redis--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>2.配置连接属性# redis 配置 spring.redis.host=47.106.8.233 spring.redis.port=6379 spring.redis.password=redis123 # 缓存过期时间,单位毫秒 spring.cache.redis.time-to-live=60000s3.创建RedisDao@Component public class RedisDao { @Autowired private StringRedisTemplate stringRedisTemplate; public void set(String key, String value) { this.stringRedisTemplate.opsForValue().set(key, value); } public String get(String key) { return this.stringRedisTemplate.opsForValue().get(key); } public void delete(String key) { this.stringRedisTemplate.delete(key); } }4.测试@RunWith(SpringRunner.class) @SpringBootTest public class RedisDaoTest { @Autowired private RedisDao redisDao; @Test public void testSet() { String key = "name"; String value = "zhangsan"; this.redisDao.set(key, value); } @Test public void testGet() { String key = "name"; String value = this.redisDao.get(key); System.out.println(value); } @Test public void testDelete() { String key = "name"; this.redisDao.delete(key); } }
2021年12月08日
162 阅读
0 评论
0 点赞
1
...
4
5
6