码迷,mamicode.com
首页 > 其他好文 > 详细

redis学习

时间:2019-03-17 15:36:42      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:介绍   red   ons   obj   清理   img   启动命令   部分   可用性   

1.1.1 配置静态IP地址

  1. 检查当前的IP地址    ifconfig

本机IP地址: 192.168.126.174

  1. 配置静态IP地址

 技术图片

 

1.1.2 当前系统架构存在的问题

说明:如果有大量的用户请求,如果频繁的读取数据库,这样的效率依然很低,一般大型公司都会采用缓存机制.当前最流行的缓存服务器Redis.

 

说明:如果有大量的用户请求,如果频繁的读取数据库,这样的效率依然很低,一般大型公司都会采用缓存机制.当前最流行的缓存服务器Redis.

 

 

1.1.1 缓存机制

缓存机制:缓存机制能够有效的降低用户访问物理设备的访问频次.缓存中的数据就是数据库中的数据.当数据库数据发现更新操作时,也应该及时更新缓存.保证数据的一致性.

实现缓存需要解决的问题:

  1. 缓存设计语言.  C语言编辑.
  2. 如何防止缓存数据丢失?  定期将数据持久化
  3. 如何控制内存大小?      LRU算法
  4. 缓存数据如何存储?什么样的数据结构??? Key-value

1.1.2 Redis介绍

Redis是一个开源(BSD许可),采用key-value结构进行数据存储,用作数据库,缓存和消息队列。它支持数据结构,如字符串,散列,列表,集合,带有范围查询的排序集,位图,超级日志,具有半径查询和流的地理空间索引。Redis具有内置复制,Lua脚本,LRU算法,事务和不同级别的磁盘持久性,并通过Redis Sentinel提供高可用性并使用Redis Cluster自动分区.

速度:读写速度平均10万/秒

1.1.3 Redis下载

http://www.redis.cn/download.html

 

1.1.4 Redis安装

  1. 上传安装文件
  2. 解压文件

 

  1. 编辑和安装

 Make:编译环境.

 

安装指令: make install

 

1.1.5 编辑redis.conf

  1. 注释IP绑定

 

  1. 关闭保护模式

 

  1. 开启后台启动

 

1.1.6 基本命令

  1. 启动命令: redis-server redis.conf
  2. 关闭命令: redis-cli -p 6379 shutdown
  3. 进入客户端: redis-cli -p 6379    
  4. 退出客户端  exit

1.2    Redis命令

1.2.1 String类型

命令

说明

案例

set

添加key-value

set username admin

get

根据key获取数据

get username

strlen

获取key的长度

strlen key

exists

判断key是否存在

exists name

返回1存在  0不存在

del

删除redis中的key

del key

Keys

用于查询符合条件的key

keys * 查询redis中全部的key

keys n?me 使用占位符获取数据

keys nam* 获取nam开头的数据  

mset

赋值多个key-value

mset key1 value1 key2 value2 key3 value3

mget

获取多个key的值

mget key1 key2

append

对某个key的值进行追加

append key value

type

检查某个key的类型

type key

select

切换redis数据库

select 0-15 redis中共有16个数据库

flushdb

清空单个数据库

flushdb

flushall

清空全部数据库

flushall

incr

自动加1

incr key

decr

自动减1

decr key

incrby

指定数值添加

incrby 10

decrby

指定数值减

decrby 10

expire

指定key的生效时间 单位秒

expire key 20

key20秒后失效

pexpire

指定key的失效时间 单位毫秒

pexpire key 2000

key 2000毫秒后失效

ttl

检查key的剩余存活时间

ttl key

persist

撤销key的失效时间

persist key

1.2.2 Hash类型

说明:可以用散列类型保存对象和属性值

例子:User对象{id:2,name:小明,age:19}

命令

说明

案例

hset

为对象添加数据

hset key field value

hget

获取对象的属性值

hget key field

hexists

判断对象的属性是否存在

HEXISTS key field

1表示存在  0表示不存在

hdel

删除hash中的属性

hdel user field [field ...]

hgetall

获取hash全部元素和值

HGETALL key

hkyes

获取hash中的所有字段

       HKEYS key

hlen

获取hash中所有属性的数量

hlen key

hmget

获取hash里面指定字段的值

hmget key field [field ...]

hmset

为hash的多个字段设定值

hmset key field value [field value ...]

hsetnx

设置hash的一个字段,只有当这个字段不存在时有效

HSETNX key field value

hstrlen

获取hash中指定key的长度

HSTRLEN key field

hvals

获取hash的所有值

HVALS user

 

1.2.3 List类型

说明:Redis中的List集合是双端循环列表,分别可以从左右两个方向插入数据.

List集合可以当做队列使用,也可以当做栈使用

队列:存入数据的方向和获取数据的方向相反

栈:存入数据的方向和获取数据的方向相同

命令

说明

案例

lpush

从队列的左边入队一个或多个元素

LPUSH key value [value ...]

rpush

从队列的右边入队一个或多个元素

RPUSH key value [value ...]

lpop

  从队列的左端出队一个元素

LPOP key

rpop

从队列的右端出队一个元素

RPOP key

lpushx

当队列存在时从队列的左侧入队一个元素

LPUSHX key value

rpushx

当队列存在时从队列的右侧入队一个元素

RPUSHx key value

lrange

从列表中获取指定返回的元素

  LRANGE key start stop

  Lrange key 0 -1 获取全部队列的数据

lrem

从存于 key 的列表里移除前 count 次出现的值为 value 的元素。 这个 count 参数通过下面几种方式影响这个操作:

  • count > 0: 从头往尾移除值为 value 的元素。
  • count < 0: 从尾往头移除值为 value 的元素。
  • count = 0: 移除所有值为 value 的元素。

 LREM list -2 “hello” 会从存于 list 的列表里移除最后两个出现的 “hello”。

需要注意的是,如果list里没有存在key就会被当作空list处理,所以当 key 不存在的时候,这个命令会返回 0。

Lset

设置 index 位置的list元素的值为 value

LSET key index value

 

1.2.4 Redis事务命令

说明:redis中操作可以添加事务的支持.一项任务可以由多个redis命令完成,如果有一个命令失败导致入库失败时.需要实现事务回滚.

命令

说明

案例

multi

标记一个事务开始

127.0.0.1:6379> MULTI

OK

exec

执行所有multi之后发的命令

127.0.0.1:6379> EXEC

 OK

discard

    丢弃所有multi之后发的命令

 

 

1.3    缓存三大问题

1.3.1 缓存穿透

条件:访问一个不存在的数据

说明:当访问一个不存在的数据时,因为缓存中没有这个key,导致缓存形同虚设.最终访问后台数据库.但是数据库中没有该数据所以返回null.

隐患:如果有人恶意频繁查询一个不存在的数据,可能会导致数据库负载高导致宕机.

总结:业务系统访问一个不存在的数据,称之为缓存穿透.

1.3.2 缓存击穿

条件:当缓存key失效/过期/未命中时,高并发访问该key

说明:如果给一个key设定了失效时间,当key失效时有一万的并发请求访问这个key,这时缓存失效,所有的请求都会访问后台数据库.称之为缓存击穿.

场景:微博热点消息访问量很大,如果该缓存失效则会直接访问后台数据库,导致数据库负载过高.

1.3.3 缓存雪崩

前提:高并发访问,缓存命中较低或者失效时

说明:假设缓存都设定了失效时间,在同一时间内缓存大量失效.如果这时用户高并发访问.缓存命中率过低.导致全部的用户访问都会访问后台真实的数据库.

场景:在高并发条件下.缓存动态更新时

 

  1. Day01.  

 

 

2   Redis高级

2.1    Redis入门

2.1.1 导入jar包

<!-- jedis -->

      <dependency>

          <groupId>redis.clients</groupId>

          <artifactId>jedis</artifactId>

          <version>${jedis.version}</version>

      </dependency>

 

      <!--添加spring-datajar包 -->

      <dependency>

          <groupId>org.springframework.data</groupId>

          <artifactId>spring-data-redis</artifactId>

          <version>1.4.1.RELEASE</version>

      </dependency>

2.1.2 String类型案例

前提:关闭防火墙 service iptables stop

/**

    * 1.通过IP和端口可以连接Redis

    * 2.操作方法就是命令

    * **/

   @Test

   public void StringTest() {

      Jedis jedis =

             new Jedis("192.168.126.174", 6379);

       String result = jedis.set("1811","今天周四");

      System.out.println("保存后的返回值为:"+result);

      System.out.println("获取数据:"+jedis.get("1811"));

   }

2.1.3 Hash类型

//操作hash

   @Test

   public void testHash() {

      Jedis jedis = new Jedis("192.168.126.174", 6379);

      jedis.hset("dog", "name","二哈");

      jedis.hset("dog", "age", "7");

      Map<String,String> map =

             jedis.hgetAll("dog");

      System.out.println(map);

   }

2.1.4 操作List集合

/**操作List集合,改数据类型,不能长期保存数据,

   数据最终会被消费.*/

   @Test

   public void testList() {

      Jedis jedis = new Jedis("192.168.126.174", 6379);

      jedis.rpush("list","1","2","3");

      String a = jedis.rpop("list");

      System.out.println(a);

   }

2.1.5 Redis事务控制

把redis当做数据库使用时,才会使用事务.

//控制redis事务问题

   @Test

   public void tx() {

      Jedis jedis = new Jedis("192.168.126.174", 6379);

      //开启事务

      Transaction transaction = jedis.multi();

      try {

          transaction.set("kk", "kk");

          transaction.set("ww", "ww");

          int a = 1/0;

          transaction.exec();

      } catch (Exception e) {

          e.printStackTrace();

          transaction.discard();

      }

   }

2.1.6 什么样的数据添加缓存

说明:应该将不变的数据,添加到缓存中.如果数据频繁的修改不适合添加缓存.

  1. 省/市/县/乡/
  2. 收货地址
  3. 商品分类目录
  4. 当用户点击商品分类按钮时,要进行商品分类的查询.
  5. 首先应该查询缓存,key必须唯一.
  6. 3.  如果缓存中的数据为null,则查询数据库.将数据库中查询的结果保存到缓存中. Key:JSON
  7. 如果缓存中有数据.将json串转为java对象,之后返回给用户.

2.2    实现商品分类缓存操作

2.2.1 实现原理步骤

2.2.2 ObjectMapper介绍

public class ObjectMapperTest {

  

   @Test

   public void objectToJSON() throws IOException {

      User user = new User();

      user.setId(100);

      user.setName("测试");

      user.setAge(10000);

      user.setSex("男");

      ObjectMapper objectMapper = new ObjectMapper();

      String json =

      objectMapper.writeValueAsString(user);

      System.out.println(json);

     

      //将json串转化为对象

      User user2 =

      objectMapper.readValue(json, User.class);

      //get方法获取属性值. set方法为属性赋值.

      System.out.println(user2.toString());

   }

  

   @SuppressWarnings("unchecked")

   @Test

   public void listToJSON() throws IOException {

      List<User> userList = new ArrayList<User>();

      User user1 = new User();

      user1.setId(1);

      user1.setName("杯子");

      user1.setAge(19);

      user1.setSex("男");

      userList.add(user1);

      ObjectMapper objectMapper = new ObjectMapper();

      String result =

             objectMapper.writeValueAsString(userList);

      System.out.println(result);

      //将JSON转化为List集合

      List<User> uList =

      objectMapper.readValue(result,ArrayList.class);

      System.out.println(uList);

   }

}

2.3    Spring整合Redis

2.3.1 编辑pro文件

 

2.3.2 编辑Spring配置文件

<!--1.创建objectMapper  -->

   <bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper"></bean>

  

   <!--2.创建Jedis对象  -->

   <bean id="jedis" class="redis.clients.jedis.Jedis">

      <constructor-arg name="host" value="${redis.host}"/>

      <constructor-arg name="port" value="${redis.port}"/>

   </bean>

2.3.3 编辑ObjectMapper工具类

public class ObjectMapperUtil {

   private static ObjectMapper mapper = new ObjectMapper();

  

   public static String toJSON(Object object) {

      String json = null;

      try {

 

          json = mapper.writeValueAsString(object);

      } catch (Exception e) {

          e.printStackTrace();

          throw new RuntimeException();

      }

      return json;

   }

  

   @SuppressWarnings("unchecked")

   public static <T> T toObject(String json,Class<?> targetClass) {

      T t = null;  //定义泛型对象

      try {

          t = (T) mapper.readValue(json,targetClass);

      } catch (Exception e) {

          e.printStackTrace();

          throw new RuntimeException();

      }

      return t;   

   }

}

2.3.4 修改Nginx配置项

#编辑后台管理服务器

   server {

      listen 80;

      server_name manage.jt.com;

      location / {

          #代理请求url路径

          #proxy_pass http://jtLinux;

          #proxy_pass http://jt;

          proxy_pass http://localhost:8091;

          proxy_connect_timeout       3; 

          proxy_read_timeout          3; 

          proxy_send_timeout          3;

      }

   }

2.3.5 修改数据库链接

jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/jtdb?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true

jdbc.username=root

jdbc.password=root

2.3.6 缓存代码实现

/**

    * 1.生成key

    * 2.查询redis缓存

    *     null: 则调用业务层方法获取数据,

    *          利用工具类封装为JSON,保存到缓存中

    *     !null:

    *          将缓存转化为对象返回

    */

   @SuppressWarnings("unchecked")

   @Override

   public List<EasyUITree> findCacheItemCat(Long parentId) {

      String key = "ITEM_CAT_" + parentId;

      String json = jedis.get(key);

      List<EasyUITree> treeList = new ArrayList<>();

      if(StringUtils.isEmpty(json)) {

          treeList = findItemCatList(parentId);

          String result =

                ObjectMapperUtil.toJSON(treeList);

          jedis.set(key, result);

          System.out.println("查询数据库!!!!!");

      }else {

          treeList = ObjectMapperUtil.toObject(json,ArrayList.class);

          System.out.println("查询缓存!!!!!!!");

      }

     

      return treeList;

   }

2.3.7 Redis缓存测试

  1. 没有缓存

 

  1. 添加缓存

 

 

2.4    Redis分片技术

2.4.1 单点redis存在问题

说明:单台redis中使用的内存大小有限.默认的内存的大小为10M,如果使用时内存不足,如何处理.

  1. 扩展内存

 

修改内存大小:

 

最大的内存大小不要超过1G  512M-1024M

  1. 采用分片方式

准备多台redis.实现内存扩容

2.4.2 Redis分片搭建

  1. 新建文件夹

mkdir shards

  1. 拷贝redis配置文件

[root@localhost redis-3.2.8]# cp redis.conf shards/redis-6379.conf

[root@localhost redis-3.2.8]# cp redis.conf shards/redis-6380.conf

[root@localhost redis-3.2.8]# cp redis.conf shards/redis-6381.conf

  1. 修改配置文件端口号

[root@localhost shards]# vim redis-6380.conf

[root@localhost shards]# vim redis-6381.conf

 

  1. 启动多台redis

[root@localhost shards]# redis-server redis-6379.conf

[root@localhost shards]# redis-server redis-6380.conf

[root@localhost shards]# redis-server redis-6381.conf

  1. 检查Redis启动是否成功

ps -ef |grep redis

 

2.4.3 Redis分片入门案例

@Test

   public void test01() {

      List<JedisShardInfo> shards =

                new ArrayList<JedisShardInfo>();

      JedisShardInfo info1 =

             new JedisShardInfo("192.168.126.174",6379);

      JedisShardInfo info2 =

             new JedisShardInfo("192.168.126.174",6380);

      JedisShardInfo info3 =

             new JedisShardInfo("192.168.126.174",6381);

      shards.add(info1);

      shards.add(info2);

      shards.add(info3);

      ShardedJedis jedis = new ShardedJedis(shards);

      jedis.set("1811","分片测试");

      System.out.println(jedis.get("1811"));

      //问:数据保存到了哪个redis节点??如何存储??

   }

2.5    Hash一致性

2.5.1 基本实现

角色: node(节点)   key

内存:node*n 实现内存扩容.

 

2.5.2 均衡性

说明:尽可能的让节点均匀的保存数据.

问题:如果没有均衡性算法,则会导致数据负载不均.

解决方法:引入虚拟节点的概念.通过虚拟节点动态的平衡数据.

 

2.5.3 单调性

说明:当节点新增时,节点信息会动态的划分,实现数据的挂载.

原则:如果节点新增时,尽肯能的保证原有的数据保持不变!只平衡部分数据.

单调性中描述节点只能新增,不能减少,如果节点个数少了.则内存缺失.分片不能使用.

  1. Day02.  

 

 

Redis高级

2.6    AOP实现redis缓存

2.6.1 定义注解

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

//反射???? 不加参数??? 方法名称 find

public @interface CacheAnno {

   String key();         //定义key值

   int index();       //参数定义位置

   Class targetClass();  //定义目标类型

   CACHE_TYPE cacheType() default CACHE_TYPE.FIND;

  

   //定义泛型类型

   enum CACHE_TYPE{

      FIND,           //定义查找

      UPDATE          //定义更新

   }

}

2.6.2 编辑切面

@Component      //交给spring容器管理

@Aspect         //标识切面

public class CacheAspect {

  

   //当执行时才注入,后期将该对象换为集群对象

   @Autowired(required=false)

   private Jedis jedis;

  

   /**

    * 控制用户是否查询数据库  目标方法

    * @param joinPoint

    * @param cacheAnno

    * @return

    */

  

   //利用环绕通知 拦截所有的缓存注解

   @Around("@annotation(cacheAnno)")

   public Object around(ProceedingJoinPoint joinPoint,CacheAnno cacheAnno) {

     

      return getObject(joinPoint,cacheAnno);

   }

   public Object getObject(ProceedingJoinPoint joinPoint, CacheAnno cacheAnno) {

      //获取参数

      CACHE_TYPE cacheType = cacheAnno.cacheType();

      String key = cacheAnno.key();

      int index = cacheAnno.index();

      Class<?> targetClass = cacheAnno.targetClass();

      //根据位置获取参数

      Long id = (Long) joinPoint.getArgs()[index];

      //拼接参数 ITEM_CAT_0

      String redisKey = key + id;

      Object object = null;

      switch (cacheType) {

          case FIND:      //表示查询缓存

             object = findObject(joinPoint,redisKey,targetClass);

             break;

          case UPDATE: //表示更新缓存

             object = updateObject(joinPoint,redisKey);

             break;

          }

     

      return object;

   }

 

   private Object findObject(ProceedingJoinPoint joinPoint, String key, Class<?> targetClass) {

      //检查缓存中是否有数据

      String result = jedis.get(key);

      Object object = null;

      try {

          if(StringUtils.isEmpty(result)) {

             //表示缓存中没有数据,则查询数据库

             object = joinPoint.proceed();

             String json = ObjectMapperUtil.toJSON(object);

             jedis.set(key, json);

             System.out.println("AOP查询真实数据库!!");

          }else {

             //表示缓存中有数据,查询缓存

             object = ObjectMapperUtil.toObject(result, targetClass);

             System.out.println("AOP查询缓存!!");

          }

      } catch (Throwable e) {

          e.printStackTrace();

          throw new RuntimeException();

      }

      return object;

   }

  

   private Object updateObject(ProceedingJoinPoint joinPoint, String redisKey) {

      //更新缓存,删除即可

      Object object = null;

      try {

          jedis.del(redisKey);

          object = joinPoint.proceed();

          System.out.println("AOP缓存删除");

      } catch (Throwable e) {

          e.printStackTrace();

          throw new RuntimeException();

      }

      return object;

   }

}

2.7    Spring整合Redis分片

2.7.1 编辑pro文件

redis.host=192.168.126.174

redis.port.a=6379

redis.port.b=6380

redis.port.c=6381

2.7.2 编辑配置文件

<!--value如果存储字符串/基本类型-->

   <!--ref存储对象-->

   <!--2.redis分片  -->

   <bean id="shardJedis" class="redis.clients.jedis.ShardedJedis">

      <constructor-arg name="shards">

          <list>

             <ref bean="info1"/>

             <ref bean="info2"/>

             <ref bean="info3"/>

          </list>

      </constructor-arg>

   </bean>

   <bean id="info1" class="redis.clients.jedis.JedisShardInfo">

      <constructor-arg name="host" value="${redis.host}"/>

      <constructor-arg name="port" value="${redis.port.a}"/>

   </bean>

   <bean id="info2" class="redis.clients.jedis.JedisShardInfo">

      <constructor-arg name="host" value="${redis.host}"/>

      <constructor-arg name="port" value="${redis.port.b}"/>

   </bean>

   <bean id="info3" class="redis.clients.jedis.JedisShardInfo">

      <constructor-arg name="host" value="${redis.host}"/>

      <constructor-arg name="port" value="${redis.port.c}"/>

   </bean>

 

2.7.3 分片缺点

  1. 安全性不好,用户可以利用客户端直接set操作,修改数据.
  2. 由于单调性的要求,节点只能增,不能减,如果redis节点宕机,整合服务不能运行. 分片没有实现高可用

2.8    Redis中哨兵机制

2.8.1 哨兵机制说明

1.前提:数据必须同步,搭建redis主从.

2.哨兵只会监听主机的状态,通过心跳机制进行检测 ping-pong

3.当哨兵发现主机3次都没有响应时,这时认为主机宕机.内部进行推选.

4.当哨兵通过读取主机的配置文件,发现当前的主机中有2个从机.所以哨兵推选一台从机当做现在的主节点.

5.当哨兵成功推选了从机当主节点时.哨兵会修改另外节点的配置文件.重新定义主从结构.

2.9    主从同步搭建

2.9.1 复制文件夹

cp -r shards sentinel

 

2.9.2 重启redis

[root@localhost sentinel]# redis-server redis-6379.conf

[root@localhost sentinel]# redis-server redis-6380.conf

[root@localhost sentinel]# redis-server redis-6381.conf

2.9.3 检查redis状态

 

2.9.4 检查节点状态信息

命令: info replication

 

2.9.5 实现主从挂载

  1. 进入6380客户端中 进行主从挂载

redis-cli -p 6380

  1. 挂载命令

SLAVEOF 192.168.126.174 6379

  1. 检查状态

 

  1. 将6381实现主从挂载.
  2. 检查主机的状态

 

2.9.6 配置哨兵

  1. 复制配置文件

cp sentinel.conf  sentinel

  1. 修改保护模式

 

  1. 修改哨兵的配置

sentinel monitor mymaster 192.168.126.174 6379 1

mymaster: 表示主机的变量名称.

IP:端口    主机的IP和端口

2:几票同意,即选举成功!!!

 

 

  1. 修改宕机的推选时间

 

  1. 修改推选失败的超时时

 

2.9.7 哨兵高可用测试

  1. 启动哨兵

redis-sentinel sentinel.conf

 

  1. 哨兵测试

说明:首先将redis主机宕机.之后等待10秒后,检查哨兵是否进行推选.

如果哨兵完成推选.并且将其余的机器更新主从结构,则哨兵测试成功!

 

2.9.8 关于哨兵配置的错误

  1. 如果哨兵选举时,内部有误.3个节点中有3主结构.这样的选举结构有问题.

将配置文件全部删除.

2.10  Spring整合哨兵

2.10.1    哨兵配置入门案例

/**

    * 参数说明

    * 1.masterName  主机的变量名称

    *  2.sentinels   哨兵的信息

    *  String=IP:端口

    */

   @Test

   public void testSentinel() {

      Set<String> sentinels = new HashSet<>();

      sentinels.add("192.168.126.174:26379");

      JedisSentinelPool pool =

      new JedisSentinelPool("mymaster", sentinels);

      Jedis jedis = pool.getResource();

      jedis.set("aa", "abc");

      System.out.println("获取redis数据:"+jedis.get("aa"));

      jedis.close();

   }

2.10.2    编辑pro文件

redis.masterName=mymaster

redis.node1=192.168.126.174:26379

2.10.3    编辑Spring配置文件

<bean id="jedisSentinelPool" class="redis.clients.jedis.JedisSentinelPool">

      <constructor-arg name="masterName" value="${redis.masterName}"/>

      <constructor-arg name="sentinels">

          <set>

             <value>${redis.node1}</value>

          </set>

      </constructor-arg>

   </bean>

2.10.4    编辑工具Service

@Service

public class RedisService {

  

   //使用时注入

   @Autowired(required=false)

   private JedisSentinelPool pool;

  

   //set get

   public void set(String key,String value) {

      Jedis jedis = pool.getResource();

      jedis.set(key, value);

      jedis.expire(key, 7*24*3600);

      jedis.close();

   }

  

   public String get(String key) {

      Jedis jedis = pool.getResource();

      String result = jedis.get(key);

      jedis.close();

      return result;

   }

}

编辑完成后,将Common打包!!

2.10.5    修改业务代码

  1. 注入工具类对象

 

  1. 编辑业务代码

 

2.10.6    页面效果展现

 

2.11  Redis持久化策略

2.11.1    Redis持久化原理

  1. redis应该定期将内存中的数据进行持久化.
  2. 当redis节点重启时.首先应该读取持久化文件.恢复内存数据.
    1. RDB模式是redis默认的持久化策略.
    2. RDB模式,能够定期将内存中的数据进行保存.
    3. RDB模式中可能会丢失数据.所以如果redis当做数据库/队列时不要使用该模式
    4. RDB模式备份效率是最高的.
    5. RDB模式备份时做的是内存的快照,并且持久化文件中,只保留最新的内存数据.持久化文件大小是可控的.
    6. 持久化文件的名称

2.11.2    RDB模式

2.11.2.1   RDB模式说明

2.11.2.2   RDB模式配置

 

  1. 持久化文件的路径

 

  1. 持久化命令

save   :立即执行持久化

   bgsave :开启另外的线程进行持久化.

  1. 默认的持久化周期

save 900 1     #在900秒内,执行一次set操作,则持久化一次

save 300 10    #在300秒内,执行10次set操作,则持久化一次

save 60 10000   #在60秒内,执行10000次set操作,则持久化一次

2.11.3    AOF模式

2.11.3.1   模式说明

  1. AOF模式默认是关闭的.需要手动的开启.
  2. AOF模式能够实现数据的实时存储,保证数据的有效性
  3. AOF模式一般使用在数据库/队列
  4. AOF模式效率低于RDB模式.
  5. AOF模式相当于记录了用户全部的操作过程,并且将用户的指令追加到持久化文件中.该持久化文件占用的空间大.恢复内存数据的时间长.
  6. 开启AOF模式

2.11.3.2   AOF模式配置

  1. AOF配置文件名称

3.持久化策略

# appendfsync always  每次执行set操作,则持久化一次

appendfsync everysec  每秒持久化一次.

# appendfsync no       由操作系统决定何时持久化一般默认15分钟

4.AOF文件保存的路径

 技术图片

 

2.12  Redis内存策略

2.12.1    内存策略由来

说明:作为一个优秀的缓存服务器,应该定义内存的大小,同时应该进行动态的维护.如果数据只增不减,.那么redis内存很快会被占满,如果后续有set操作时,则必然会报错.

策略:

  1. 必须设定redis内存最大值. 10M 最大1024M
  2. 如果内存使用量达75%时,则优化内存数据.则动态清理数据.

2.12.2    LRU算法

内存管理的一种页面置换算法,对于在内存中但又不用的数据块(内存块)叫做LRU,操作系统会根据哪些数据属于LRU而将其移出内存而腾出空间来加载另外的数据。

关于操作系统的内存管理,如何节省利用容量不大的内存为最多的进程提供资源,一直是研究的重要方向。而内存的虚拟存储管理,是现在最通用,最成功的方式—— 在内存有限的情况下,扩展一部分外存作为虚拟内存,真正的内存只存储当前运行时所用得到信息。这无疑极大地扩充了内存的功能,极大地提高了计算机的并发度。虚拟页式存储管理,则是将进程所需空间划分为多个页面,内存中只存放当前所需页面,其余页面放入外存的管理方式。

然而,有利就有弊,虚拟页式存储管理增加了进程所需的内存空间,却也带来了运行时间变长这一缺点:进程运行过程中,不可避免地要把在外存中存放的一些信息和内存中已有的进行交换,由于外存的低速,这一步骤所花费的时间不可忽略。因而,采取尽量好的算法以减少读取外存的次数,也是相当有意义的事情。

2.12.3    Redis中如何控制内存大小

volatile-lru :在设定了超时时间的数据中采用LRU方式删除数据.

allkeys-lru  :在所有的key中采用LRU算法删除数据.

volatile-random :在设定了超时时间的key中随机删除.

allkeys-random  :所有的key随机删除.

volatile-ttl    : 在设定了超时时间的key中根据ttl(显示存活的剩余时间),将马上要超时的数据提前删除.

noeviction  :该配置为默认值.当内存占满时,报错返回.

2.12.4    修改内存策略

 

2.12.5    Redis分片和哨兵总结

说明:

  1. redis单台,存储数据量很少
  2. redis分片.最主要的是实现了内存的扩容!!!!,缺点没有实现高可用.
  3. Redis哨兵.主要实现了Redis的高可用.但是哨兵没有实现高可用,内部维护繁琐,工作也不使用.
  4. Redis集群.实现分片+哨兵的全部的功能.并且不需要第三方监管.

Redis集群是通过节点内部进行推选,不需要依赖第三方.

搭建集群时,主机的个数是奇数个.

redis学习

标签:介绍   red   ons   obj   清理   img   启动命令   部分   可用性   

原文地址:https://www.cnblogs.com/douguihun/p/10546927.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!