Redis01(安装、连接)

0、Redis

参考文档:https://www.cnblogs.com/linianhui/p/what-problem-does-redis-solve.html

1、redis是什么?

一款基于内存高速缓存数据库

2、redis在是什么方面使用?

缓存,毫无疑问这是Redis当今最为人熟知的使用场景。再提升服务器性能方面非常有效;

排行榜,如果使用传统的关系型数据库来做这个事儿,非常的麻烦,而利用Redis的SortSet数据结构能够非常方便搞定;

计算器/限速器,利用Redis中原子性的自增操作,我们可以统计类似用户点赞数、用户访问数等,这类操作如果用MySQL,频繁的读写会带来相当大的压力;限速器比较典型的使用场景是限制某个用户访问某个API的频率,常用的有抢购时,防止用户疯狂点击带来不必要的压力;

好友关系,利用集合的一些命令,比如求交集、并集、差集等。可以方便搞定一些共同好友、共同爱好之类的功能;

简单消息队列,除了Redis自身的发布/订阅模式,我们也可以利用List来实现一个队列机制,比如:到货通知、邮件发送之类的需求,不需要高可靠,但是会带来非常大的DB压力,完全可以用List来完成异步解耦;

Session共享,以PHP为例,默认Session是保存在服务器的文件中,如果是集群服务,同一个用户过来可能落在不同机器上,这就会导致用户频繁登陆;采用Redis保存Session后,无论用户落在那台机器上都能够获取到对应的Session信息。

3、为什么使用redis?

比如缓存可以用Memcache,Session共享还能用MySql来实现,消息队列可以用RabbitMQ,我们为什么一定要用Redis呢?

1.速度快,完全基于内存,使用C语言实现,网络层使用epoll解决高并发问题,单线程模型避免了不必要的上下文切换及竞争条件;注意:单线程仅仅是说在网络请求这一模块上用一个线程处理客户端的请求,像持久化它就会重开一个线程/进程去进行处理

2.丰富的数据类型,Redis有8种数据类型,当然常用的主要是 String、Hash、List、Set、 SortSet 这5种类型,他们都是基于键值的方式组织数据。每一种数据类型提供了非常丰富的操作命令,可以满足绝大部分需求,如果有特殊需求还能自己通过 lua 脚本自己创建新的命令(具备原子性)
Redis还提供了像慢查询分析、性能测试、Pipeline、事务、Lua自定义命令、Bitmaps、HyperLogLog、发布/订阅、Geo等个性化功能。

3.支持持久化(rdb,aof)它的编译安装也是非常的简单,没有任何的系统依赖;各种客户端的语言支持也是非常完善。另外它还支持事务、主从复制、高可用、分布式。

4、redis使用带来的哪些问题?

1.缓存和数据库间数据一致性问题
分布式环境下(单机就不用说了)非常容易出现缓存和数据库间的数据一致性问题,针对这一点的话,只能说,如果你的项目对缓存的要求是强一致性的,那么请不要使用缓存。我们只能采取合适的策略来降低缓存和数据库间数据不一致的概率,而无法保证两者间的强一致性。合适的策略包括 合适的缓存更新策略,更新数据库后要及时更新缓存、缓存失败时增加重试机制,例如MQ模式的消息队列

2.缓存雪崩

缓存雪崩:缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉
事前:尽量保证整个 redis 集群的高可用性,发现机器宕机尽快补上。选择合适的内存淘汰策略。
事中:本地ehcache缓存 + hystrix限流&降级,避免MySQL崩掉
事后:利用 redis 持久化机制保存的数据尽快恢复缓存

3.缓存穿透
缓存穿透:大量缓存中不存在的请求key访问直接落到数据库,一般是恶意攻击;
解决:从DB中查询出来数据为空,也进行空数据的缓存,避免DB数据为空也每次都进行数据库查询;
使用布隆过滤器,但是会增加一定的复杂度及存在一定的误判率;

5、redis自己的理解

客户需要功能显示当前热点新闻信息,用户每次请求,都需要去数据库查询当前的热点新闻信息,由于当前功能访问人数量大,所以将查到的数据缓存到在服务器上,刚开始可以,后来服务器内存就会爆满。这样就需要单独一台专门存储缓存服务器,作为redis服务器,减轻项目服务器的压力。但是redis服务器数据有时候会丢失,所有的缓存丢失了,大量的请求查询就到达了数据库,这就是缓存雪崩,这样就用到了redis的持久化,将预先保存到磁盘的redis持久化文件,redis重启将(rdb、aof)加载进redis内存,redis就重新生效了。redis服务器也会挂掉,如果挂掉就需要备份的机器重新补上空缺,但是管理员不可能随时监控,这就需要配置redis的架构使用,(哨兵监察主机主机挂掉选举从机成为主机,主从复制保证从机的内容跟主机一样),有了哨兵和主从复制,解决了redis的主机挂掉。之后,单台服务器的是有上限的,这就需要配置redis集群,对于用户来说没有什么差别,对于redis服务器集群,每台服务器只负责其中的一部分,让这些所有的服务器构成一个整体。保证了redis服务器安全稳定的提供服务。

1、命令

1.1常用命令

cd: 切换目录

ls: 查看当前或指定目录下的文件 -a -l

mkdir: 创建目录 -p 递归创建

touch:创建文件

pwd: 查看当前所在的目录

cp: 复制文件或者目录

[root@master qy114]# cp  yy/* -r  test  #拷贝路径下所有文件 到对应的目录,如果子目录必须 加-r 循环拷贝 test是文件夹

mv: 重命名 或剪切

rm: 删除 -r(删除目录) -f(强制删除)

cat: 查看文件所有内容

tail num: 查看文件尾部num行的内容 日志

vi: (编辑文件内容) -----一般模式 - ------i 编辑模式- esc:进入一般模式 :wq (推出并保存) q! 强制退出 不保存

查找vmtoolsd进程的id

ps -e | awk '$4=="vmtoolsd"{print $1}'
ps -ef | awk 'BEGIN{ print "begin..."} END{print "end..."} $8=="-bash"{print $2}'
ps -ef | grep redis

1.2 用户名

1.useradd 用户名 : 创建用户

2.passwd 用户名 密码 : 重置密码

3.groupadd 组名: 创建组

4.useradd -g 组名 用户名: 创建用户并添加到指定组中

5.usermod -g 组名 用户名;

1.3 修改文件的权限

 chmod  数字   文件

1.4 防火墙的命令

systemctl status firewalld 查看防火墙的状态

systemctl stop firewalld 关闭防火墙

systemctl start firewalld 开启防火墙

systemctl disabled firewalld 永久关闭

1.5 添加端口号 在防火墙中

firewall-cmd --zone=public --add-port=3306/tcp --permanent (permanent 永久)

1.6 压缩文件

tar -zxvf 压缩文件 解压文件到当前目录

1.7 查看进程

ps -ef | grep 进程名

2.NOSQL的介绍

NOSQL是对非关系型数据库的概况,NOSQL翻译(NOT ONLY SQL 不仅仅是sql).适合大数据的存储。

2.1 NOSQL 和RDBMS(关系型数据库管理)区别

.关系型数据库RDBMS:

​ 1.结构化数据库

​ 2.结构化查询语句,定义语句。

​ 3. 数据和关系都存储在表中

. 4 支持事务管理 ACID

  **NOSQL:**

    1.没有结构化查询语句

    2.存储数据  key-value.面向列存储(HBASE),面向文档存储(Mogondb)

    3.极易扩展。

2.2 NOSQL产品有哪些

redis :

mogondb

memcache

hbase:

*1,Memcached*

挥发性(临时性)的键值存储

一般作为关系型数据库的缓存来使用

具有非常快的处理速度

由于存在数据丢失的可能,所以一般用来处理不需要持久保存的数据

用于需要使用expires时(需要定期清除数据)

使用一致性散列(Consistent Hashing)算法来分散数据

*2********,Redis*

兼具Memcached和Tokyo Tyrant优势的键值存储

擅长处理数组类型的数据

具有非常快的处理速度

可以高速处理时间序列的数据,易于处理集合运算

拥有很多可以进行原子操作的方法

使用一致性散列(Consistent Hashing)算法来分散数据

*3********,MongoDB*

面向无需定义表结构的文档数据

具有非常快的处理速度

通过BSON的形式可以保存和查询任何类型的数据

无法进行JOIN处理,但是可以通过嵌入(embed)来实现同样的功能

使用sharding(范围分割)算法来分散数据

3、redis简介

redis是nosql中使用最多的非关系型数据库,使用c语言编写,低层存储以key-value键值对存储。

特点:

  1. 读写速度快。 读110000/s 写81000/s
  2. 以key-value键值对存储。
  3. 存储的数据类型丰富。存储string,list(队列),set(集合),hash(哈希),zSet(有序集合)。(redis支持哪些数据类型。)
  4. 易于集群搭建。
  5. 可以在内存中运行,并且可以存储到磁盘上

3.1 Redis的安装。

https://redis.io/download 该网址可以下载redis

3.2 安装C语言的环境(**安装redis前确认联网)

yum -y install gcc-c++     网络安装gcc-c++  install 安装  -y 一直同意

3.2 上传redis安装文件 上传到 /usr/local/

使用xshell

3.3 在该目录解压该文件

tar -zxvf redis-5.0.8.tar.gz

3.4 进入解压后的目录 源码

cd /usr/local/redis-5.0.8

3.5 编译该文件

make

3.6 安装编译后的文件

make install

3.7 启动redis

在这里插入图片描述

redis-server 启动redis服务的。

redis-server  /目录/redis.conf

客户端连接redis服务

redis-cli  默认连接的是本地的redis服务 并且端口号为6379

redis-cli -h(ip)  -p(端口号)
redis-cli -h 127.0.0.1 -p 6379

在这里插入图片描述

客户发送一个指令ping 服务器响应一个pong的结果

启动redis后台运行,修改redis.conf第136行 设置成yes

vim redis.conf
136 daemonize yes

然后重启服务

[root@master redis-5.0.8]# redis-server redis.conf
9864:C 17 Aug 2020 18:48:15.948 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
9864:C 17 Aug 2020 18:48:15.948 # Redis version=5.0.8, bits=64, commit=00000000, modified=0, pid=9864, just started
9864:C 17 Aug 2020 18:48:15.948 # Configuration loaded
[root@master redis-5.0.8]# ps -A | grep redis
  9865 ?        00:00:00 redis-server
[root@master redis-5.0.8]# redis-cli 
127.0.0.1:6379> ping
PONG

4、Redis 常见命令

set key value :往redis中存放字符串数据。

get key: 获取指定key的value值

keys * : 查询所有的key

del key: 删除指定的key

exists key: 判断key是否存在 存在返回1 不存在返回0

expire key : 为指定的key设置时间。

ttl key :查看指定的key的剩余时间

flushdb: 清空该数据库中的所有数据。 <测试用>

5、使用redis-plus连接redis

关闭防火墙

systemctl status firewalld

将redis.conf配置文件中bind 127.0.0.1修改成0.0.0.0

vim /usr/local/redis-5.0.8/redis.conf

重启服务

redis-server /usr/local/redis-5.0.8/redis.conf

启动redisplus连接vmvare中redis
一种使用ip,一种使用ssh
在这里插入图片描述
如果连接失败,注意:
1.redis服务没有开启
2.Redis端口号被防火墙拦截

6、 java连接redis

6.1 java连接redis

  <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.1.0</version>
        </dependency>
       //创建一个Jedis
        Jedis jedis = new Jedis("192.168.91.100", 6379);//操作的哪个redis
        String ping = jedis.ping();
        System.out.println(ping); //pong
        jedis.set("k1", "v1");
        jedis.setnx("num", "1");
        System.out.println(jedis.incr("num"));
        jedis.hset("hset1", "name", "张三");
        System.out.println(jedis.get("k1"));
        jedis.close();

6.2 spring连接redis

<!-- jar包版本声明 -->
<properties>
    <spring.version>4.3.24.RELEASE</spring.version>
    <jedis.version>3.1.0</jedis.version>
</properties>
<!-- 声明需要的依赖的具体的资源 -->
<dependencies>
    <!-- 导入spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!--jedis的jar包-->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>${jedis.version}</version>
    </dependency>
</dependencies>

spring主配置文件中加入bean

    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="20"/>
        <property name="maxIdle" value="10"/>
        <property name="maxWaitMillis" value="10000"/>
    </bean>
    <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
        <constructor-arg name="poolConfig" ref="poolConfig"></constructor-arg>
        <constructor-arg name="host" value="192.168.91.100"/>
        <constructor-arg name="port" value="6379"/>
    </bean>

测试

  ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring-redis.xml");
        JedisPool jedisPool = applicationContext.getBean(JedisPool.class);
        Jedis jedis = jedisPool.getResource();
        Map<String, String> hashmap = new HashMap<String, String>();
        hashmap.put("name", "zs");
        hashmap.put("age", "18");
        jedis.hset("user", hashmap);
        Map<String, String> user = jedis.hgetAll("user");
        System.out.println(user);
        jedis.close();

spring使用redis作为缓存

@Autowired
private JedisPool jedisPool;
public List<Department> getDepts() {
   Jedis jedis = jedisPool.getResource();
   String deptAll = jedis.get("deptAll");
   if(deptAll==null){
      System.out.println("缓存中不存在该数据,需要查询数据库");

      List<Department> list = departmentMapper.selectByExample(null);
      //放进redis缓存
      jedis.set("deptAll",JSON.toJSONString(list));//,JSON.toJSONString(list) @ResponseBody
      return list;
   }else{
      System.out.println("缓存中存在该数据");
      //JSON.parseArray(deptAll,Department.class); 把json字符串转化为java对象。等价于controller @RequestBody
      return JSON.parseArray(deptAll,Department.class);
   }
}

7.3 springboot连接redis

spring:
  redis:
    jedis:
      pool:
        max-active: 20
        min-idle: 10
        max-wait: 10000

    host: 192.168.91.100
    port: 6379
 @Test
    void contextLoads() {

        //操作字符串类型 需要获取该字符串的对象stringRedisTemplate.opsForValue();
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
    /*   opsForValue.set("k1","v1");
       opsForValue.set("k2","v2");
       System.out.println(opsForValue.get("k1"));*/
        HashOperations<String, Object, Object> forHash = stringRedisTemplate.opsForHash();
        forHash.put("h1", "name", "张三");
        System.out.println(forHash.get("h1", "name"));
        
        Map<String, String> map = new HashMap<>();
        map.put("age", "15");
        map.put("name", "简素言");
        map.put("addr", "郑州");
        forHash.putAll("h2", map);
        Collection list = new ArrayList<>();
        list.add("name");
        list.add("age");
        list.add("addr");
        System.out.println(forHash.multiGet("h2", list));
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值