1.redis是什么
Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker.
It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams.
Redis has built-in replication, Lua scripting, LRU eviction, transactions and different levels of on-disk persistence, and provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster
Redis是一个开源(BSD许可),内存数据结构存储,用作数据库,缓存和消息代理
它支持的数据结构有字符串、哈希表散列(键值对)、列表、集合、可随机查询的有序集合、bitmaps位图、hyperloglogs
基数统计、用于半径查询的地理位置索引
Redis已经内置功能有主从复制,LUA脚本,最近最少使用算法失效,事物、各种级别硬盘持久化,Redis哨兵保证可用性、Redis集群自动分片.....
 
简单来说我们把redis当作一个高性能的key-value数据库来使用
 
2.redis的下载安装配置
  • linux的直接去官网下载就行了,下面都有介绍,通过make命令进行安装,看不懂英语的百度下如何使用chrome自带的翻译插件
windows的比较麻烦,还得去github上下载,访问比较卡的可以参考我之前的一篇文章,直接设置hosts, 跳过DNS解析的过程
  • 下载完毕后解压,随便找个redis版本,比如redis-windows-master\redis-windows-master\downloads\redis64-3.0.501.zip解压后放到自己合适的目录下, 例E:\redis64-3.0.501
  • 在解压目录下,按住shift , 鼠标右击, 选中在此处打开命令窗口, 输入命令
redis-server.exe redis.windows.conf
如果不想每次都手写命令,可以写个脚本
目录结构
E:\redis\redis64-3.0.501-6379
在此目录下 新建一个txt @echo off
redis-server.exe redis.windows.conf
@pause 重命名为startRedisServer.bat
bat结尾的是windows可识别的批处理程序 可以直接执行命令窗口的命令
@echo off DOS批处理中的,
不想显示器显示 dos批处理中 的 每条命令 , 加 echo off
“echo off”也是命令,它本身也会显示,如果连这条也不显示,就在前面加个“@”。 @本身就是一条指令,意思是跟在它后面的指令的执行及结果都不会在DOS界面上显示出来 pause暂停命令
运行该命令时,将显示消息:请按任意键继续 . . .,一般用于看清楚屏幕上显示的内容 然后新建一个txt,在E:\redis目录下
@echo off
cd redis64-3.0.501-6379
startRedisServer.bat 重命名为start6379.cmd cmd开启客户端
@echo off
cd redis64-3.0.501-6379
redis-cli
@pause
 

 

添加描述

出现此画面代表redis运行成功了,在此目录下接着打开一个命令行
输入如下命令 >redis-cli > set age 32 ok > get age "32"
注1:如果不想每次都进入目录下执行命令,可参考前面的zookeeper,在 系统path下配置环境变量,
这样就能在任意目录下通过redis-cli访问redis了(猜测window系统会根据命令行的命令先去 --系统path路径下找--可执行的文件)
注2:如果不想关闭cmd窗口就终止redis服务,可把redis设置成windows下的服务
设置服务命令

redis-server --service-install redis.windows-service.conf --loglevel verbose

卸载服务:redis-server --service-uninstall

开启服务:redis-server --service-start

停止服务:redis-server --service-stop

通过右击计算机---计算机管理--服务和应用程序--服务可查看多出了一个redis服务

注3:E:\redis64-3.0.501\redis.windows-service.conf
Redis安装的服务默认加载的是该文件,自定义配置信息
 
附:redis解压包和 可视化界面客户端
redis客户端工具大家找找吧,超过10M我就不上传了

 

添加描述

 
 
3.redis实战,spring和redis的结合
项目中如何使用redis呢,思路3部曲,先导包,再配置,最后测试
我自建的项目都是maven方式管理jar包
首先在pom.xml文件添加依赖,因为我用的spring框架,所以导了一个spring-data-redis,jackson包是为了能保持对象

<dependencies>

        <dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.1</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.2.RELEASE</version>
</dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.1.0</version>
</dependency> </dependencies>
在src/main/resources目录下新建一个redis.properties文件里面配置redis的信息
#访问地址
redis.host=127.0.0.1
#访问端口
redis.port=6379
#注意,如果没有password,此处不设置值,但这一项要保留
redis.password= #最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。
redis.maxIdle=300
#连接池的最大数据库连接数。设为0表示无限制
redis.maxActive=600
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
redis.maxWait=1000
#在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;
redis.testOnBorrow=true
在applicationContext.xml下配置好自动注解扫描,bean文件扫描
<!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 --> <context:component-scan base-package="com.one.*" /> <!--写自己的包的路径 --> <!-- 加载bean配置 --> <import resource="classpath*:conf/beans-*.xml"/> <!-- 因为我的bean文件都是 conf目录下的 名字以beans-开头的 例如 beans-redis.xml -->
 

 

目录结构

在beans-redis.xml文件里配置bean信息
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd "> <!--  如果在多个spring配置文件中引入<context:property-placeholder .../>标签,
最后需要加上ignore-unresolvable="true",否则会报错。 ignore-unresolvable="true"
在加载第一个property-placeholder时出现解析不了的占位符进行忽略掉 -->
<!-- 连接池基本参数配置,类似数据库连接池 -->
<context:property-placeholder location="classpath:redis.properties"
ignore-unresolvable="true" /> <!-- redis连接池 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.maxActive}" />
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean> <!-- 连接池配置,类似数据库连接池 -->
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.host}"></property>
<property name="port" value="${redis.port}"></property>
<!-- <property name="password" value="${redis.pass}"></property> -->
<property name="poolConfig" ref="poolConfig"></property>
</bean> <!--redis操作模版,使用该对象可以操作redis -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >
<property name="connectionFactory" ref="jedisConnectionFactory" />
<!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!! -->
<property name="keySerializer" >
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer" >
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
</property>
<!--开启事务 -->
<property name="enableTransactionSupport" value="true"></property>
</bean > <!-- 下面这个是整合Mybatis的二级缓存使用的
<bean id="redisCacheTransfer" class="cn.qlq.jedis.RedisCacheTransfer">
<property name="jedisConnectionFactory" ref="jedisConnectionFactory" />
</bean>--> </beans>
最后编写测试类开启测试啦, 工具类网上找找, 下面的代码注入RedisUtil报错,涉及的先都去掉
package com.one.redis;

import java.io.InputStream;
import java.util.*; import javax.annotation.Resource; import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import redis.clients.jedis.Jedis; @RunWith(SpringJUnit4ClassRunner.class)
// @ContextConfiguration("classpath:applicationContext-*.xml")
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
// 加载配置文件
@SuppressWarnings("all")
public class RedisTest { // @Autowired
// private RedisUtil redisUtil; // 1.导包
// applicationContext.xml <import resource="classpath*:conf/beans-*.xml"/>
// beans-redis.xml
// <bean id="redisTemplate"
// class="org.springframework.data.redis.core.RedisTemplate" >
@Resource(name = "redisTemplate")
private RedisTemplate redisTemplate; @Test
public void testSpringRedis() {
// stringRedisTemplate的操作
// String读写
redisTemplate.delete("myStr");
redisTemplate.opsForValue().set("myStr", "skyLine");
System.out.println(redisTemplate.opsForValue().get("myStr"));
System.out.println("---------------");
// org.springframework.data.redis.RedisConnectionFailureException:
// Cannot get Jedis connection; nested exception is
// redis.clients.jedis.exceptions.JedisConnectionException: Could not
// get a resource from the pool // List读写
redisTemplate.delete("myList");
redisTemplate.opsForList().rightPush("myList", "T");
redisTemplate.opsForList().rightPush("myList", "L");
redisTemplate.opsForList().leftPush("myList", "A");
List<String> listCache = redisTemplate.opsForList().range("myList", 0,
-1);
for (String s : listCache) {
System.out.println(s);
}
System.out.println("---------------"); // Set读写
redisTemplate.delete("mySet");
redisTemplate.opsForSet().add("mySet", "A");
redisTemplate.opsForSet().add("mySet", "B");
redisTemplate.opsForSet().add("mySet", "C");
redisTemplate.opsForSet().add("mySet", "C");
Set<String> setCache = redisTemplate.opsForSet().members("mySet");
for (String s : setCache) {
System.out.println(s);
}
System.out.println("---------------");// ABC // Hash读写
redisTemplate.delete("myHash");
redisTemplate.opsForHash().put("myHash", "BJ", "北京");
redisTemplate.opsForHash().put("myHash", "SH", "上海");
redisTemplate.opsForHash().put("myHash", "HN", "河南");
Map<String, String> hashCache = redisTemplate.opsForHash().entries(
"myHash");
for (Map.Entry entry : hashCache.entrySet()) {
System.out.println(entry.getKey() + " - " + entry.getValue());
}
System.out.println("---------------"); // Redis Incrby 命令将 key 中储存的数字加上指定的增量值,如果 key 不存在,那么 key 的值会先被初始化为 0
// ,然后再执行 INCR 操作
double stringValueDouble = redisTemplate.opsForValue().increment(
"doubleValue", 5);
System.out.println("通过increment(K key, double delta)方法以增量方式存储double值:"
+ stringValueDouble);
// incrBy:将 key 所储存的值加上给定的增量值(increment) 。
Jedis jedis = new Jedis("127.0.0.1", 6379); jedis.incrBy("key3", 5);
String v3 = jedis.get("key3");
System.out.println("结果:" + v3); }
@Test
public void delete() { redisTemplate.delete("myStr");
redisTemplate.delete("mySet");
redisTemplate.delete("myHash");
redisTemplate.delete("key3"); String str = "string";// 1.字符串
redisUtil.set("str", str);
System.out.println(redisTemplate.opsForValue().get("str"));
} @Autowired
private RedisUtil redisUtil; @Test
public void testSpringRedis2() {
String str = "string";// 1.字符串
List<String> list = new ArrayList<String>();// list
list.add("0");
list.add("中国");
list.add("2");
Set<String> set = new HashSet<String>();// set
set.add("0");
set.add("中国");
set.add("2");
Map<String, Object> map = new HashMap();// map
map.put("key1", "str1");
map.put("key2", "中国");
map.put("key3", "str3"); redisUtil.del("myStr", "str");// 删除数据 // 1.字符串操作
System.out.println(str); redisUtil.set("str", str);
redisUtil.expire("str", 120);// 指定失效时间为2分钟
String str1 = (String) redisUtil.get("str"); System.out.println(redisTemplate.opsForValue().get("str")); System.out.println("str1= " + str1); // 2.list操作
redisUtil.lSet("list", list);
redisUtil.expire("list", 120);// 指定失效时间为2分钟
List<Object> list1 = redisUtil.lGet("list", 0, -1);
System.out.println(list1); // 3.set操作
redisUtil.sSet("set", set);
redisUtil.expire("set", 120);// 指定失效时间为2分钟
Set<Object> set1 = redisUtil.sGet("set");
System.out.println(set1); // 3.map操作
redisUtil.hmset("map", map);
redisUtil.expire("map", 120);// 指定失效时间为2分钟
Map<Object, Object> map1 = redisUtil.hmget("map");
System.out.println(map1); } // TODO 哨兵集群 // TODO CDN
}
这里要说明下,真实这些配置文件的地址其实都在classes 也就是classpath根目录下
E:\e\eclipse\work\one-parent\one-common\target\classes,如果读spring源码就大概能知道,spring是如何先读xml,然后在通过classpath 判断 怎么读配置文件
有的没引入单元测试包的
<properties>

        <junit.version>4.9</junit.version>
<spring-version>3.1.2.RELEASE</spring-version>
</properties> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-version}</version>
</dependency>
4.redis哨兵集群
上面再介绍redis的基本情况的时候,官网把这个哨兵 sentinel放在最前面讲, 应该是很重要, 主要我们项目中封装了一层又一层,找了好久才找到redis的真实地址,才知道运用了哨兵集群
//遍历哨兵地址和端口号 执行xxx 可忽略 Jedis jedis = new Jedis("", ); HostAndPort master = MyHostAndPort.toHostAndPort(jedis.sentinelGetMasterAddrByName(masterName));
首先是这样,既然redis要集群, 那么就得有集群管理工具,Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance),Redis 的 Sentinel 为Redis提供了高可用性,包括 监控,提醒,自动故障迁移
什么是高可用, 就是你挂了,我接着跑,生产环境偶尔会遇到服务器宕机,redis连接失败等情况
  • 先来看redis集群,简单来说就是master-slave,主从复制, slave同步master的数据, 用于读写分离和容灾恢复
参考https://blog.csdn.net/u010648555/article/details/79427606

这么操作
1.先将E:\redis\redis64-3.0.501复制三份,分别命名为redis64-3.0.501-6379,redis64-3.0.501-6379,
redis64-3.0.501-6381 2.修改6380 6381下的redis.windows.conf文件,改成各自对应的端口号,都做6379的从节点 port 6380 # slaveof <masterip> <masterport>
slaveof 127.0.0.1 6379 3.通过上面介绍的cmd脚本形式启动6379, 然后启动6380,然后启动6379客户端,看下图
命令info replication
 
 
 
主节点可读可写,从节点只能读不可写,具体的可以自己试试
发现我写个打开redis-cli脚本,打开6380,弹出的命令窗口还是127.0.0.1:6379>, 于是修改redis.windows-service.conf
也没用,后来查原来是从节点是要加个参数
@echo off cd redis64-3.0.501-6380 redis-cli -p 6380 @pause
 
 
当主节点重新启动后,从节点的状态【从节点依然可以连接主节点】
 
 
  • redis主从复制的缺点: 每次slave断开重连后,都要重新全部同步一遍, 复制延迟,如果master不能写入,会导致业务出错,可用性不高,所以采用哨兵模式
  • 接着上文的基础看redis-sentinel模式的配置,已经有了主从配置,E:\redis\redis64-3.0.501-6379在每个文件夹下添加一个sentinel.conf的配置文件,这个文件在官网下载linux版本目录下直接有
 
在复制的redis文件夹里也加下该文件,然后改一下端口,26380,和 26381
可以在redis解压目录下 通过redis-server.exe redis.windows.conf
redis-server.exe sentinel.conf --sentinel 命令, 先启动Redis集群,再启动哨兵实例 也可以像之前那样,写个脚本执行 示例文件做了详细的配置说明,启动不了,估计是里面哪里配置有误,懒得找了,用下面的简化版sentinel.conf
port 26379
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 3000
sentinel failover-timeout mymaster 10000
sentinel config-epoch mymaster 0 执行后你会发现该文件有变化,写入了从服务器的信息
# Generated by CONFIG REWRITE
dir "E:\\redis\\redis64-3.0.501-6379"
sentinel leader-epoch mymaster 0
sentinel known-slave mymaster 127.0.0.1 6380
sentinel known-slave mymaster 127.0.0.1 6381
sentinel current-epoch 0 如果报Invalid argument during startup: Failed to open the .conf file:
一般都是配置文件的问题,把它从其他地方关闭
 

 

生成哨兵ID(Sentinel ID),并自动识别主服务器和从服务器

启动后,可以使用shutdown命令关闭master,看slave选举日志,80 81竞争master,恢复79后,79就作为slave了
Redis-Sentinel是Redis官方推荐的高可用性(HA) 解决方案,Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。Sentinel可以监视任意多个主服务器(复用),以及主服务器属下的从服务器,并在被监视的主服务器下线时,自动执行故障转移操作。
 
为了防止sentinel的单点故障,可以对sentinel进行集群化,创建多个sentinel。
 

 
5.几个常见的redis问题
  • Redis 有哪些类型
官方文档: strings, hashes, 我理解就是hashmap, lists, sets, sorted sets with range queries, 后面3个不知道是啥 bitmaps, hyperloglogs, geospatial indexes with radius queries and streams.
  • Redis 内部结构
了解一点,redis使用 c实现的, 使用kev-value的形式存储数据, 熟悉c语言的更好理解一点结构
1.大多数情况下数据以字符串形式展现 2.双端链表,Redis list的实现为一个双向链表,即可以支持反向查找和遍历 3.字典 4.跳跃表 Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序
 
 
  • 聊聊 Redis 使用场景
1.项目里面比如系统参数配置用到的是string, 还有经常要用的比如产品库存 2.Hash, 项目中用到的是 银行编码+缓存唯一标识做key , 身份证 , 用户ID key , 电子账号 , 用户ID 3.Redis的list是每个子元素都是String类型的双向链表,可以通过push和pop操作从列表的头部或者尾部添加或者删除元素, 这样List即可以作为栈,也可以作为队列。 list可以用在消息队列场景,最新消息排行 比如一些最新评论,展示在首页的可以用redis , 只有点击--显示全部--才需要访问数据库, 降低数据库
  • Redis 持久化机制
1.RDB持久化 Redis DataBase 2.AOF持久化 Append Only File
  • Redis 如何实现持久化
1.RDB : 默认的,内存中数据以 快照 的方式写入到 二进制文件 中,默认的文件名为dump.rdb 例子: save 900 1 #900秒内如果超过1个key被修改,则发起快照保存 方便备份,恢复快,最大化 Redis 的性能 不能避免在服务器故障时丢失数据:RDB 文件需要保存整个数据集的状态,并不是一个轻松的操作 可能会至少 5 分钟才保存一次 RDB 文件。 在这种情况下, 一旦发生故障停机, 你就可能会丢失好几分钟的数据 2.AOF : 当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容 AOF 持久化会让 Redis 变得非常耐久(much more durable) AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机, 也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求) appendonly yes //启用aof持久化方式 # appendfsync always //每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用 appendfsync everysec //每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐 # appendfsync no //完全依赖os,性能最好,持久化没保证
  • Redis 集群方案与实现
参考上面的 哨兵集群
  • Redis 为什么是单线程的
因为Redis是基于内存的操作,CPU不是Redis的瓶颈, 100000+的QPS(每秒内查询次数) per second Redis的瓶颈最有可能是机器内存的大小或者网络带宽 了解: 单线程的方式是无法发挥多核CPU 性能,不过我们可以通过在单机开多个Redis 实例 可以在同一个多核的服务器中,可以启动多个实例,组成master-master或者master-slave的形式 耗时的读命令可以完全在slave进行 单线程,只是在处理我们的网络请求的时候只有一个线程来处理 一个正式的Redis Server运行的时候肯定是不止一个线程的
  • 缓存崩溃
集群,哨兵部署起来 redis备份和预热 缓存预热:系统上线后,将相关的缓存数据直接加载到缓存系统,比如我们用一个job,可以手动执行,去加载所有需要缓存的信息 项目中, 先查缓存, 缓存不存在则从数据库查, 查到结果,置入缓存 由于原有缓存失效,新缓存未到期间(例如:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期), 所有原本应该访问缓存的请求都去查询数据库了 一个简单方案就时讲缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值, 比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件 缓存标记,我们项目中就使用了一个标记string字段: 在项目上线后, 将key :isReliable value:1做缓存,设置永久 先去查缓存,如果缓存中没有,可能是redis全部挂了, 也可能是真的没有数据, 那么查该标记,如果为空可能就是缓存挂了, 再去查数据库的里的表,因为我们做了分表要一次性查20张表的数据 性能很低 如果不为空,说明缓存没挂,在根据业务逻辑进行处理,说明可能真的没存,直接找对应的表
  • 缓存降级
当访问量剧增,仍然要保证核心服务可用, 非核心服务提供有损的也可以,比如本来显示余额的 给它显示一个 "客观别急" 降级方式:可以通过一些数据进行自动降级 通过人工开关进行降级 服务降级的目的,是为了防止Redis服务故障,导致数据库跟着一起发生雪崩问题。因此,对于不重要的缓存数据, 可以采取服务降级策略,例如一个比较常见的做法就是,Redis出现问题,不去数据库查询,而是直接返回默认值给用户
缓存穿透: 缓存命中率问题, 用户查数据,数据库没有,则没有置入缓存,缓存中没有,每次都去查数据库 如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短, 最长不超过五分钟。通过这个直接设置的默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库 可以给key设置一些格式规则,然后查询之前先过滤掉不符合规则的Key
  • 使用缓存的合理性问题
1.热点数据 ,当然一些系统参数可以设置永久 2.包括上面提到的缓存降级,预热,穿透等等 3.频繁修改的数据要考虑是否会经常读

啰里吧嗦redis的更多相关文章

  1. 啰里吧嗦CountDownLatch

    java.util.concurrent Class CountDownLatch 目录 CountDownLatch 是什么 CountDownLatch是一个同步工具类,它允许一个或多个线程一直等 ...

  2. 啰里吧嗦jvm

    一.为什么要了解jvm 有次做项目的时候,程序run起来的时候,总是报OutOfMemoryError,有老司机教我们用jconsole.exe看内存溢出问题 就是这货启动jconsole后,发现一个 ...

  3. 啰里吧嗦kafka

    1.kafka是什么 kafka官网: http://kafka.apache.org/ kafka是一种高吞吐量的分布式发布订阅消息系统,用它可以在不同系统中间传递分发消息 2.zookeeper是 ...

  4. 啰里吧嗦式讲解java静态代理动态代理模式

    一.为啥写这个 文章写的比较啰嗦,有些东西可以不看,因为想看懂框架, 想了解SSH或者SSM框架的设计原理和设计思路, 又去重新看了一遍反射和注解, 然后看别人的博客说想要看懂框架得先看懂设计模式,于 ...

  5. 一步步学习操作系统(1)——参照ucos,在STM32上实现一个简单的多任务(“啰里啰嗦版”)

    该篇为“啰里啰嗦版”,另有相应的“精简版”供参考 “不到长城非好汉:不做OS,枉为程序员” OS之于程序员,如同梵蒂冈之于天主教徒,那永远都是块神圣的领土.若今生不能亲历之,实乃憾事! 但是,圣域不是 ...

  6. .netcore里使用StackExchange.Redis TimeOut 情况解决方法

    在用StackExchange.Redis这个组件时候,时不时会出现异常TimeOut解决方法如下, 解决方法: 在Program的Main入口方法里添加一句话: System.Threading.T ...

  7. java里常用的redis客户端简介

    Redis的各种语言客户端列表,请参见Redis Client.其中Java客户端在github上start最高的是Jedis和Redisson.Jedis提供了完整Redis命令,而Redisson ...

  8. Redis(六):java里常用的redis客户端(Jedis和Redisson)

    Redis的各种语言客户端列表,请参见Redis Client.其中Java客户端在github上start最高的是Jedis和Redisson.Jedis提供了完整Redis命令,而Redisson ...

  9. 啰哩吧嗦式讲解在windows 家庭版安装docker

    1.docker是什么,为什么要使用docker Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中, 然后发布到任何流行的 Linux 机器上,也可以实 ...

随机推荐

  1. Struts2乱码问题的解决办法

    乱码问题的起因在于数据在web系统的各个层中间传递的时候编码不同,比如页面使用GB18030而中间层使用UTF-8.由于struts2默认使用的就是UTF-8编码,所以在页面如果使用的是其他的编码格式 ...

  2. jsp的九大内置对象(查询资料,搬砖所得)

    此笔记大部分摘自大神https://www.cnblogs.com/SimonHu1993/,部分通过网上搜寻补充. 1.Request内置对象(类型:HttpServletRequest    表示 ...

  3. python中实现三目运算

    python中没有其他语言中的三元表达式,不过有类似的实现方法 如: a = 1 b =2 k = 3 if a>b else 4 上面的代码就是python中实现三目运算的一个小demo, 如 ...

  4. Tree-669. Trim a Binary Search Tree

    Given a binary search tree and the lowest and highest boundaries as L and R, trim the tree so that a ...

  5. linux crontab 实现每秒执行的实例

    linux crontab 命令,最小的执行时间是一分钟.如需要在小于一分钟内重复执行,可以有两个方法实现. 1.使用延时来实现每N秒执行 原理:通过延时方法 sleep N  来实现每N秒执行. 创 ...

  6. springmvc执行流程详细介绍

    1.什么是MVC MVC是Model View Controller的缩写,它是一个设计模式 2.springmvc执行流程详细介绍 第一步:发起请求到前端控制器(DispatcherServlet) ...

  7. 2019 rode of my LeetCode

    基于自己的算法实操水平如此之菜,开始开启leetcode狂刷之路! 2019先定个小目标100题. 2018年经历了辞职到考研失利,我觉得这大概是一生中最低谷的时候了吧. 2019年收拾心情重新开始好 ...

  8. POJ 1221

    #include <iostream> #define MAXN 500 using namespace std; unsigned dp[MAXN][MAXN]; int main() ...

  9. POJ 1032

    #include<iostream> using namespace std; int main() { int n; int num; ; int i,j; cin>>num ...

  10. script全局变量

    javascript全局变量的生命周期是:直到页面关闭才失效.否则一直有用. 方式1 1 2 var test; var test = 5; 需注意的是该句不能包含在function内,否则是局部变量 ...