zoukankan      html  css  js  c++  java
  • Redis入门

    Redis介绍

    一种全新的内存型数据库。

    Redis是key-value型的NoSQL(Not only SQL)数据库(非关系型数据库);

    Redis将数据存储在内存中,同时也能持久化到磁盘;

    Redis常用于缓存,利用内存的高效提高程序的处理速度。

    笔记:

    内存RAM,关机重启后数据会丢失,redis支持将数据持久化到硬盘上;

    系统和数据库服务直接可以增加redis服务器,系统直接从redis中获取数据,速度更快。

    Redis特点

    速度快;广泛的语言支持;持久化;多种数据结构;主从复制;分布式于高可用。

    笔记:

    开源,可以根据需求开发特定的redis工具

    高可用:哨兵机制,防止一台redis服务器当机系统就无法使用。

    Redis的安装与启动

    1)Linux系统上安装Redis:

    进入redis官网:https://redis.io/

      因为redis是服务器端的NoSQL数据库,官方默认不会提供windows下的redis最新版本,只提供tar.gz格式tar.gz格式的redis最新版本的下载,所以redis的安装平台首选Linux系统。

    点击Check the downloads page.

    可以看到具体的安装过程

    步骤:

    进入linux系统,打开终端

    cd /usr/local  #进入local目录,一般习惯将程序安装在这个目录下

    mkdir redis  #创建一个名为redis的文件夹,用于安装 redis

    cd redis  #进入redis目录

    yum install gcc  #底层依赖gcc才能使用make命令进行编译,需先安装gcc编译包

    wget http://download.redis.io/releases/redis-6.0.8.tar.gz #下载最新redis安装包

    tar xzf redis-6.0.8.tar.gz  #解压安装包

    cd redis-6.0.8/  #进入解压后的目录,里面存放的是redis源代码等,其中redis.conf是redis的核心配置文件

    make  #编译源代码

    cd src  #进入源代码目录,其中redis-server是redis的启动命令,redis-cli是redis的连接客户端 

    cd .. #返回上一级目录

    ./src/redis-server redis.conf  #启动redis

    使用make编译时报错:

    经查资料了解到,centos7安装redis6.x版本要正常编译,需要升级gcc的版本 

    gcc -v #查看gcc版本

    centos7默认gcc版本为4.8.5

    redis6.x版本需要的gcc版本为5.3及以上

    //升级gcc到9以上

    yum -y install centos-release-scl

    yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils 

    //临时将此时的gcc版本改为9(scl命令启用只是临时的,推出xshell或者重启就会恢复到原来的gcc版本)。

    scl enable devtoolset-9 bash

    //或永久改变

    echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile

    这时再查询gcc版本,变为了9.x版本

    重新使用make编译,往下进行流程 

    看到下图文字表示编译成功:

    redis启动成功界面:

    2)windows系统上安装Redis:

    微软对redis重构,提供了能够在windows上运行的redis。

    github地址:https://github.com/MicrosoftArchive/redis

    不过版本很久没有更新了,截止目前,最后一次更新的才3.2.100版本

    点击relese page

    下载.zip版本,版本有些老,作为学习可以用,生产环境服务器上不可以

    解压安装包 

    redis-server.exe是启动程序

    redis-windows.conf是redis核心配置文件

    cmd进入终端

    进入redis目录,启动redis,下图是启动成功界面。

    reids的常用基本配置

    Redis通用命令

    笔记:

    例1:守护进程方式启动redis,即后台运行 

    解决终端重启或关闭后redis进程关闭的问题。

    启动linux终端,进入redis目录:

    cd redis-6.0.8/

    打开并编辑redis配置文件:

    vim redis.conf

    定位到文件的146行,将daemonize的参数由no改为yes,表示允许后台启动(按i进入编辑模式,修改后:wq保存并退出)

    关闭redis服务:

    使用kill命令(不推荐,后续会学习使用redis-cli关闭命令)。

    kill -9 进程号 

    例2:使用redis-cli客户端

    进入redis目录:

    cd redis-6.0.8/

    启动redis-cli,进入redis客户端,可以输入redis命令并执行:

    ./src/redis-cli

    检查redis服务是否正常启动:

    ping

    ping 看是否能提供服务 ping  显示pong正常

    退出cli:

    exit 

    使用cli关闭redis服务:

    ./src/redis-cli shutdown

    实际项目一般不会用默认端口6379,防止黑客或第三方攻击。通过修改redis.conf文件来修改默认端口:

    定位到配置文件92行,修改port后的端口号

    修改日志文件名字(保存在redis目录下): 

    定位到171行,logfile ,默认为空字符串

    重新启动redis可以看到变化:

    后台启动,端口号为6380

    这时,再连接cli客户端,提示6379连接被拒绝,因为我们把端口改为了6380,需要连接6380端口。

    在cli中操作redis数据库:

    select 数据库名字  #切换数据库 

    redis中数据库的名字就是一个一个的数字  默认16个  序号0~15,超过会提示越界

    修改cong配置文件来修改数据库总数:

    定位到186行。

    但这样只要加上端口号就可以通过redis-cli访问数据很危险,需要设置密码:

    定位到conf配置文件507行。 

    把 requirepass 那一行注释打开,修改密码

    这样就必须提供密码才能访问redis数据了。

    cli连接身份验证:

    auth 密码

    指定数据文件的保存路径修改,很重要,但很少修改,默认是当前文件夹:

    定位到conf配置文件第263行

    redis目录中的另一个重要文件: 

    dump.rdb 文件,用来保存的全量数据(包含任何操作),防止redis突然当机造成数据丢失。

    Redis数据类型

    1)String-字符串类型

    结构:

    命令:

     

    单个kv不要太大,否则会影响存取数据的速度、效率;

    value是数字时,底层也是以字符串类型存储的。

    2)Hash键值类型

    结构:

    用于存储结构化数据。

    命令:

    3)List列表类型

    结构:

      List列表就是一系列字符串的“数组”,按插入顺序排列;

      List列表最大长度为2的32次方-1,可以包含40亿个元素。

    命令:

       

      

     lrange 获取list中数据,后面两个参数是开始范围 start end,取全部值参数为 0 -1

    4)Set集合类型

    结构:

      Set集合是字符串的无序集合,集合成员是唯一的。 

    命令:

      sadd 集合名字 字符串(数组) #创建一个集合,插入成员

      smembers 集合名字  #查看某集合所有成员

       

       

       插入成员时,返回1表示插入成功,返回0表示失败

      

      集合求交集:

      sinter 集合1 集合2

      集合求并集:

      sunion 集合1 集合2

      集合求差集(1有,2没有的):

      sdiff 集合1 集合2  

    5)Zset集合类型

    结构:

      Zset集合是字符串的有序集合,集合成员是唯一的。在Set集合基础上加了一个分数参数,使集合有序。

      默认按照分数升序排列。

    命令:

        zadd 集合名字 分数 字符串 #创建一个集合,插入成员

      zrange 集合名字 start end  #用于输出指定范围的元素,0 -1 表示全部元素

       

    Redis的Java客户端——Jedis

    redis官网为每种语言都提供了对应的客户端,Jedis是Java语言开发的Redis客户端工具包;

    Jedis只是对Redis命令的封装,掌握Redis命令便可以轻松上手。

    1)Jedis使用演示

    一般redis服务器仅做redis服务使用,我们的java程序要用另外一台服务器。

    多个服务器之间进行来回通讯,redis的配置要进行一些更改。

    1⃣️默认情况下只允许在本机访问redis,要想远程访问需要修改两个参数:

    定位到conf文件88行,protected-mode 保护模式,yes表示只允许指定的地址才能访问redis服务,

    开发需要,要先设置为no,允许其他主机也能访问redis。

    定位到69行,bind 默认 127.0.0.1 后面的地址表示能访问redis的主体ip

    修改为 bind 0.0.0.0 所有主机可访问,实际项目不能这样,不安全,要设置成具体服务器地址

    2⃣️设置防火墙对6379端口放行

     正常第一次放行是不会有红色warning的,这里是因为之前已经放行了,所以才warning提示。

    3⃣️查看redis服务器IP地址,联机时需要用到

    ifconfig

    4⃣️下载安装jedis

    进入redis官网,点击Clients

    点击java

    里面有许多开源的redis java客户端,点击图标,进入github官网

    里面有安装的方式,下面使用maven方式下载

     目前最新版本为3.3.0版本

     

    2.9.0版本最稳定,暂用这一版本。

    5⃣️jedis使用入门

    启动idea➡️create new project➡️maven➡️next

    在pom文件中加入redis依赖

    测试代码:

     1 public class JedisTestor {
     2     public static void main(String[] args) {
     3         Jedis jedis = new Jedis("192.168.132.144" , 6379);//服务器地址,端口号
     4         try {
     5             jedis.auth("12345");//验证密码
     6             jedis.select(2);///切换到数据库2
     7             System.out.println("Redis连接成功");
     8             //字符串
     9             jedis.set("sn" , "7781-9938");
    10             String sn = jedis.get("sn");
    11             System.out.println(sn);
    12             jedis.mset(new String[]{"title" , "婴幼儿奶粉" , "num" , "20"});
    13             List<String> goods =  jedis.mget(new String[]{"sn" , "title" , "num"});
    14             System.out.println(goods);
    15             Long num = jedis.incr("num");
    16             System.out.println(num);
    17             //Hash
    18             jedis.hset("student:3312" , "name" , "张晓明");
    19             String name = jedis.hget("student:3312" , "name");
    20             System.out.println(name);
    21             Map<String,String> studentMap = new HashMap();
    22             studentMap.put("name", "李兰");
    23             studentMap.put("age", "18");
    24             studentMap.put("id", "3313");
    25             jedis.hmset("student:3313", studentMap);
    26             Map<String,String> smap =  jedis.hgetAll("student:3313");
    27             System.out.println(smap);
    28             //List
    29             jedis.del("letter");
    30             jedis.rpush("letter" , new String[]{"d" , "e" , "f"});
    31             jedis.lpush("letter" ,  new String[]{"c" , "b" , "a"});
    32             List<String> letter =  jedis.lrange("letter" , 0 , -1);
    33             jedis.lpop("letter");
    34             jedis.rpop("letter");
    35             letter = jedis.lrange("letter", 0, -1);
    36             System.out.println(letter);
    37         }catch(Exception e){
    38             e.printStackTrace();
    39         }finally {
    40             jedis.close();//关闭jedis连接
    41         }
    42 
    43     }
    44 }

    注意:redis中1个汉子3个字节,一个字符串返回的长度也是按字节来算的

    2)利用Jedis缓存数据

    用redis做缓存,需具备的特性:数据不能太大,且更新频率比较低的数据

    将java对象存入redis(转换为json存,用时在将json转换回来,需要用到fastjson)

    测试代码:

     1 public class CacheSample {
     2     public CacheSample(){
     3         Jedis jedis = new Jedis("192.168.132.144");//如果是默认端口号6379,可以不写第二个参数
     4         try {
     5             List<Goods> goodsList = new ArrayList<Goods>();
     6             goodsList.add(new Goods(8818, "红富士苹果", "", 3.5f));
     7             goodsList.add(new Goods(8819, "进口脐橙", "", 5f));
     8             goodsList.add(new Goods(8820, "进口香蕉", "", 25f));
     9             jedis.auth("12345");
    10             jedis.select(3);
    11             for (Goods goods : goodsList) {
    12                 String json = JSON.toJSONString(goods);
    13                 System.out.println(json);
    14                 String key = "goods:" + goods.getGoodsId();
    15                 jedis.set(key , json);
    16             }
    17         } catch (Exception e) {
    18             e.printStackTrace();
    19         }finally {
    20             jedis.close();
    21         }
    22     }
    23 
    24     public static void main(String[] args) {
    25         new CacheSample();
    26         System.out.printf("请输入要查询的商品编号:");
    27         String goodsId = new Scanner(System.in).next();
    28         Jedis jedis = new Jedis("192.168.132.144");
    29         try{
    30             jedis.auth("12345");
    31             jedis.select(3);
    32             String key = "goods:" + goodsId;
    33             if(jedis.exists(key)){
    34                 String json = jedis.get(key);
    35                 System.out.println(json);
    36                 Goods g = JSON.parseObject(json, Goods.class);//将json转换为Goods类对象
    37                 System.out.println(g.getGoodsName());
    38                 System.out.println(g.getPrice());
    39             }else{
    40                 System.out.println("您输入的商品编号不存在,请重新输入!");
    41             }
    42         }catch(Exception e){
    43             e.printStackTrace();
    44         }finally {
    45             jedis.close();
    46         }
    47     }
    48 }

    java对象

     1 public class Goods {
     2     private Integer goodsId;
     3     private String goodsName;
     4     private String description;
     5     private Float price;
     6 
     7     public Goods(){
     8 
     9     }
    10 
    11     public Goods(Integer goodsId, String goodsName, String description, Float price) {
    12         this.goodsId = goodsId;
    13         this.goodsName = goodsName;
    14         this.description = description;
    15         this.price = price;
    16     }
    17 
    18     public Integer getGoodsId() {
    19         return goodsId;
    20     }
    21 
    22     public void setGoodsId(Integer goodsId) {
    23         this.goodsId = goodsId;
    24     }
    25 
    26     public String getGoodsName() {
    27         return goodsName;
    28     }
    29 
    30     public void setGoodsName(String goodsName) {
    31         this.goodsName = goodsName;
    32     }
    33 
    34     public String getDescription() {
    35         return description;
    36     }
    37 
    38     public void setDescription(String description) {
    39         this.description = description;
    40     }
    41 
    42     public Float getPrice() {
    43         return price;
    44     }
    45 
    46     public void setPrice(Float price) {
    47         this.price = price;
    48     }
    49 }
    View Code

    报错:

    connection refused

    原因:

    1.服务器地址错了

    2.物理网络没有调通

  • 相关阅读:
    ModSecurity for Nginx
    一些好用的nginx第三方模块
    ModSecurity--web应用防火墙
    mycat表拆分操作教程
    .NET解析HTML库集合
    MySQL分库分表
    Redis配置文件参数说明
    redis优化优秀文选
    MySQL订单分库分表多维度查询
    每秒处理10万订单乐视集团支付架构
  • 原文地址:https://www.cnblogs.com/superjishere/p/13789449.html
Copyright © 2011-2022 走看看