Redis基础

Redis

REmote Dictionary Server (远程字典服务器)
开源免费,由C语言编写,遵守BCD协议(用4位二进制数来表示1位十进制数中的0~9这10个数码,是一种二进制的数字编码形式,用二进制编码的十进制代码),是一个高性能的(key-value)分布式内存数据库

与其他的key-value缓存相比,redis有三个特点

1.支持数据持久化,可以将内存中数据保存在磁盘中。

2.除了简单的key-value类型的数据,还支持list,set,zset,hash等数据结构的储存。

3.支持数据的备份,通过主从模式。

redis的优点
1.性能极高,redis的读的速度是110000/s,写的速度是81000/s.

2.丰富的数据类型,支持二进制的 Strings, Lists, Hashes, Sets 及 Ordered Sets

3.原子性,redis的所有操作都是原子性的,并且支持几个操作全并后的原子性执行(事务)。

4.丰富的特性,redis支持pubilsh/subscribe通知,key过期等特性

5.采用单线程, 避免了多线程的消耗cpu,上下文竞争,死锁等多种问题。

6.使用I/O复用模型,非阻塞IO。

应用场景
1.缓存(数据查询,短连接,新闻内容,商品内容等)
2.聊天室在线好友列表
3.任务队列(秒杀,抢购,12306等)
4.应用排行榜
5.网站访问统计
6.数据过期处理(可以精确到毫秒)
7.分布式集群架构中的session问题

#Redis的下载与安装

压缩包下载
英文地址 Http://redis.io/
中文地址 Http://www.redis.cn/

编译环境
redis是由c语言编写的,需要下载c语言编译环境

yum install gcc-c++

提示 都输入y

将下载的redis压缩包上传到Linux文件夹并解压到想要的文件夹
进如 解压后的redis文件夹

cd redis-5.0.5

执行make 指令

make

安装到指定文件夹

make PREFIX=/usr/local/myapps/redis install

配置文件

Redis启动需要一个配置文件,可以修改端口号信息。将redis解压的文件夹中的redis.conf文件复制到安装目录

cp redis.conf /usr/local/myapps/redis

安装结束

Redis的使用

Redis的前端模式启动
直接运行bin/redis-server将使前端模式启动,前端模式启动的缺点是启动完成后,不能再进行其他操作,如果 要操作必须使用ctrl+c,同时redis-server程序结束。

./redis-server

Redis的后端模式启动
后端默认不能启动,需要修改配置文件

vi redis.conf

改为
daemonize yes
如果被注释掉了 消除注释就行

启动服务器(加上配置文件)

./bin/redis-server ./redis.conf

启动客户端
本机
./bin/redis-cli

通过Ip 和端口号
./bin/redis-cli -h ip地址 -p 端口号
端口号默认6379

测试

ping

如果收到pong回复 说明连接成功

关闭
1.强制结束程序。强制终止Redis进程可能会导致redis持久化数据丢失。

kill -9 pid

2.向Redis发送SHUTDOWN命令 (关闭默认端口)

./bin/redis-cli shutdown

redis-desktop-manager操作redis
类似navcat管理mysql一样的图形化管理
1.修改redis.conf文件中的bind参数

bind linux的ip地址
(如果修改了bind ,就需要使用./bin/redis-cli -h ip地址 -p 端口号 连接客户端)

2.关闭防火墙连接Ip即可

Redis的数据结构

数据类型说明
String(字符串)可以保存字符串,整数,浮点数
List(列表一个链表,每一个节点都包含一个字符串
Set(集合)一个无序收集器,每一个元素都是不重复的字符串
HASH(哈希散列表)键值对对应的无序列表
ZSET (有序列表)一个依靠分值大小排序的有序集合,可以包含字符串,整数,浮点数。分值
HyperLogLog(基数)计算重复的值,以确定重复的值

Redis的基本操作

更多其他的操作:http://doc.redisfans.com/index.html

1.String
单个:
set key value

get key

del key
多个:
mset key1 value1 key2 value2

mget key1 key2

del key1 key2

在这里插入图片描述

对于整数型的变量可以自增自减

incr key
decr key
如果key 是未定义的 会自动定义key 值为零 然后开始计算

增加或减少指定数字

incrby key incrNumber 负数减少
decrby key decrNumber 负数增加

在这里插入图片描述

2.Hash散列
提供字段和字段值的映射,字段值只能是字符串,相当于对象格式储存
单个字段:

hset key field value

hget key field

hdel key field
现在可以直接使用hset 设置多个字段 但不能用hget获得多个字段
多个字段:
hmset key field1 value1 field2 value2

hmget key field1 field2

hdel key field1 field2
获取所有字段:
hgetall key

在这里插入图片描述

3.list
Redis的list是采用来链表来存储,双向链表存储数据
特点:增删快、查询慢.这个队列是有序的。
左:
lpush key value value

lpop key

右:
rpush key value value

rpop key

获取列表中元素个数
llen key

查看某段的所有元素
lrange key begin end

没有rrange在这里插入图片描述
4.set

sadd key member member

srem key member member

获得所有集合的元素
smembers key

判断元素是否在集合中
sismember key member
在这里插入图片描述
5.zset
zadd key score member member
zrem key member member

获得一个范围的元素
zrevrange key begin end (加上withscores会同时显示分数)

获得元素的分数
zscore key member
在这里插入图片描述

6.hyoperloglog
HyperLogLog是一种使用随机化的算法,以少量内存提供集合中唯一元素数量的近似值。 HyperLogLog 可以接受多个元素作为输入,并给出输入元素的基数(集合中不同元素的数量)估算值。

HyperLogLog 的优点是,即使输入元素的数量或者体积非常非常大,计算基数所需的空间总是固定的、并且是很 小的。

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计 算基数时,元素越多耗费内存就越多的集合形成鲜明对比。 但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像 集合那样,返回输入的各个元素

将指定的元素添加到hyperloglog里
pfadd key element element

计算基数估算值
pfcount key key key key

多个hyperloglog合并为一个hyperloglog
pfmerge destkey sourekey sourekey
在这里插入图片描述
7.其他常用指令

语法作用
keys hh*查询以hh开头的key
keys *查询所有key
exists key是否存在key true->1 false->0
rename oldkey newkey重命名一个key
type key返回值所对应的类型
EXPIRE key seconds设置key的生存时间(单位:s)
ttl查看key剩余的生成时间
presist key清除生存时间
info获取服务器信息和统计
flushdb删除当前选着数据库中的所有key
flushall删库跑路(笑)
select number选择第几个数据库
move key number把当前数据库的某个key转移到number库

Redis的事务

开始事务
multi
执行事务
exec
在这里插入图片描述

Redis的发布订阅

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。 Redis 客户端可以订阅任意数量的频道。

在这里插入图片描述
在这里插入图片描述
以两个为例

idea连接redis

pom 添加依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <java.version>11</java.version>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>
    <groupId>com.redis</groupId>
    <artifactId>testredis</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
    </dependencies>

</project>

jedis直接连接

    Jedis jedis = new Jedis("192.168.206.128",6379);
        jedis.set("demo1","hahaha1");
        String demo1 = jedis.get("demo1");
        System.out.println("demo1的值:"+demo1);
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

jedis数据池
public class Demo2 {
    public static void main(String[] args) {
        //创建连接池工具类的配置对象
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(10); //设置jedis连接的空闲数量
        config.setMaxTotal(20);//设置总连接数
        //创建连接池对象
        JedisPool jedisPool = null;
        Jedis resource = null;
        try {
            jedisPool = new JedisPool("192.168.206.128", 6379);
            // 获得连接池实例
            resource = jedisPool.getResource();
            resource.set("student1","zhangsan");
            String student1 = resource.get("student1");
            System.out.println("学生1:"+student1);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //虽然没有编译异常 但以防其他异常 导致资源未关闭 还是try catch finally
            if(jedisPool != null) {
                jedisPool.close();
            }
            if(resource != null){
                resource.close();
            }
        }
        //关闭资源
    }
}

Redis的持久化方式

redis 会将数据存放在硬盘中实现持久化保存

有两种方式

1.RDB持久化(默认)

RDB 是以二进制文件,是在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化 的文件,达到数据恢复。

优点:使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能
缺点:RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。所以这种方式更适合 数据要求不严谨的时候。
这里说的这个执行数据写入到临时文件的时间点是可以通过配置来自己确定的,通过配置redis 在 n 秒内如果超过 m 个 key 被修改这执行一次 RDB 操作。这个操作就类似于在这个时间点来保存一次 Redis 的所有数据,一次快照 数据。所有这个持久化方法也通常叫做 snapshots。

在redis,conf中的配置

#dbfilename:持久化数据存储在本地的文件
 dbfilename dump.rdb 
 #dir:持久化数据存储在本地的路径,如果是在/redis/redis-5.0.5/src下启动的redis-cli,则数据会存储在当前 src目录下 
 dir ./ 
##snapshot触发的时机,save
##如下为900秒后,至少有一个变更操作,才会snapshot
##对于此值的设置,需要谨慎,评估系统的变更操作密集程度
 ##可以通过“save”来关闭snapshot功能
 #save时间,以下分别表示更改了1个key时间隔900s进行持久化存储;更改了10个key300s进行存储;更改10000个 key60s进行存储。
  save 900 1 
  save 300 10 
  save 60 10000
##当snapshot时出现错误无法继续时,是否阻塞客户端“变更操作”,“错误”可能因为磁盘已满/磁盘故障/OS级别异常等
stop-writes-on-bgsave-error yes 
##是否启用rdb文件压缩,默认为“yes”,压缩往往意味着“额外的cpu消耗”,同时也意味这较小的文件尺寸以及较短的网 络传输时间 
 rdbcompression yes

2.AOF
Append-Only File
将“操作 + 数据”以格式化指令的方式追加到操作日志文件的尾部,在 append 操作返回后(已经 写入到文件或者将要写入),才进行实际的数据变更,“日志文件”保存了历史所有的操作过程;当 server 需要数据 恢复时,可以直接 replay 此日志文件,即可还原所有的操作过程。AOF 相对可靠,AOF 文件内容是字符串,非常 容易阅读和解析。

优点:可以保持更高的数据完整性,如果设置追加 file 的时间是 1s,如果 redis 发生故障,最多会丢失 1s 的数 据;且如果日志写入不完整支持 redis-check-aof 来进行日志修复;AOF 文件没被 rewrite 之前(文件过大时会对 命令进行合并重写),可以删除其中的某些命令(比如误操作的 flushall)。

缺点:AOF 文件比 RDB 文件大,且恢复速度慢

可以简单的认为 AOF 就是日志文件,此文件只会记录“变更操作”(例如:set/del 等),如果 server 中持续的大 量变更操作,将会导致 AOF 文件非常的庞大,意味着 server 失效后,数据恢复的过程将会很长;事实上,一条数 据经过多次变更,将会产生多条 AOF 记录,其实只要保存当前的状态,历史的操作记录是可以抛弃的;因为 AOF 持久化模式还伴生了“AOF rewrite”。

AOF 的特性决定了它相对比较安全。如果 AOF 文件正在被 写入时突然 server 失效,有可能导致文件的最后一次记录是不完整,可以通过手工或者程序的方式去检测并修 正不完整的记录,以便通过 aof 文件恢复能够正常;如果你的 redis 持久化手段中有 aof,那么在 server 故障失效后再次启动前,需要检测 aof 文件的完整性。

##此选项为aof功能的开关,默认为“no”,可以通过“yes”来开启aof功能
##只有在“yes”下,aof重写/文件同步等特性才会生效 
appendonly yes
##指定aof文件名称
appendfilename appendonly.aof 
##指定aof操作中文件同步策略,有三个合法值:always everysec no,默认为everysec appendfsync everysec 
##在aof-rewrite期间,appendfsync是否暂缓文件同步,"no"表示“不暂缓”,“yes”表示“暂缓”,默认为“no”
no-appendfsync-on-rewrite no 
##aof文件rewrite触发的最小文件尺寸(mb,gb),只有大于此aof文件大于此尺寸是才会触发rewrite,默认“64mb”,建 议“512mb” auto-aof-rewrite-min-size 64mb 
##相对于“上一次”rewrite,本次rewrite触发时aof文件应该增长的百分比。
##每一次rewrite之后,redis都会记录下此时“新aof”文件的大小(例如A),那么当aof文件增长到A*(1 + p)之后 ##触发下一次rewrite,每一次aof记录的添加,都会检测当前aof文件的尺寸。 
auto-aof-rewrite-percentage 100

RDB和AOF的区别
RDB: RDB是在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,达到数据 恢复。

优点:使用单独子进程来进行持久化,主进程不会进行任何IO操作,保证了redis的高性能
缺点:RDB是间隔一段时间进行持久化,如果持久化之间redis发生故障,会发生数据丢失。
AOF: Append-only file,
将“操作 + 数据”以格式化指令的方式追加到操作日志文件的尾部,在append操作返回后(已经写 入到文件或者即将写入),才进行实际的数据变更,“日志文件”保存了历史所有的操作过程;当server需要数据恢复 时,可以直接replay此日志文件,即可还原所有的操作过程。
AOF相对可靠,它和mysql中bin.log、apache.log、 zookeeper中txn-log简直异曲同工。AOF文件内容是字符串,非常容易阅读和解析。

优点:可以保持更高的数据完整性,如果设置追加file的时间是1s,如果redis发生故障,最多会丢失1s的数据;且 如果日志写入不完整支持redis-check-aof来进行日志修复;AOF文件没被rewrite之前(文件过大时会对命令进行 合并重写),可以删除其中的某些命令(比如误操作的flushall)。

缺点:AOF文件比RDB文件大,且恢复速度慢。

Redis主从搭建

主机不需要修改,修改从机即可

1.复制出从机
2.修改从机的redis.conf
replicaof 主机ip 主机端口号

port 6380 //多个从机 就继续加一

3.清除从机中的持久化文件
4.启动从机
主机宕机 从机可以使用SLAVEOF NO ONE命令变为主机

哨兵模式

哨兵主要是用来监听主服务器是否正常运行,当主机宕机,选举一个从机当主机。

配置哨兵
1.创建 哨兵配置文件 sentinel.conf
从源码配置redis-5.0.5/sentinel.conf中复制内 容,
也可以直接自定义该文件到从机bin目录下
vi sentinel.conf

sentinel monitor mastername IP(127.0.0.1) 6379 1

mastername 监控主数据的名称,自定义
127.0.0.1:监控主数据库的IP;
6379:端口
1:最低选举为主机票数

2.启动哨兵
哨兵是一个单独的进程,启动之前确保主从服务是正常的。先启动主服务,后启动从服务

把日志写入指定的文件

./redis-sentinel ./sentinel.conf >sent.log &
启动redis服务后,程序会自动配置文件sentinel.conf,并生成内容

哨兵启动

./redis-server sentinel.conf --sentinel

启动哨兵的时候,修改了哨兵的配置文件。如果需要再次启动哨兵,需要删除myid唯一标示。

Redis 集群

集群特点
1.所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.

2.节点的fail是通过集群中超过半数的节点检测有效时整个集群才生效.

3.客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可

4.redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value

心跳机制 (heartbeat)

1.集群中所有master参与投票,如果半数以上master节点与其中一个master节点通信超过(cluster-node-timeout), 认为该master节点挂掉.

2.什么时候整个集群不可用(cluster_state:fail)?
① 如果集群任意master挂掉,且当前master没有slave,则集群进入fail状态。也可以理解成集群的[0-16383]slot映 射不完全时进入fail状态。
② 如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态。

搭建集群
创建集群目录 目录名自定义
mkdir redis-cluster

创建六个节点目录 复制六份redis文件夹(删除持久化文件)
修改redis.conf配置文件
Cluster-enable yes
修改端口 不同即可

启动所有redis(可写个脚本)

创建集群
redis-cli --cluster create ip:port ip:port --cluster-replicas 1

连接集群
./bin/redis-cli -h 127.0.0.1 -p 7001 -c

idea连接集群
pom 依赖与上一样

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

public class Demo3 {
    public static void main(String[] args) {
        //创建一个集合保存集群信息
        Set<HostAndPort> set = new HashSet<>();
        set.add(new HostAndPort("192.168.206.128",7001));
        set.add(new HostAndPort("192.168.206.128",7002));
        set.add(new HostAndPort("192.168.206.128",7003));
        set.add(new HostAndPort("192.168.206.128",7004));
        set.add(new HostAndPort("192.168.206.128",7005));
        set.add(new HostAndPort("192.168.206.128",7006));
        //通过集群操作对象
        JedisCluster jedisCluster = new JedisCluster(set);
        jedisCluster.set("uname","hhw");
        String s = jedisCluster.get("uname");
        System.out.println(s);
        try {
            jedisCluster.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值