Redis基础知识

本文详细介绍了Redis的基础操作,包括安装配置、数据类型如String、Hash、List、Set、SortSet的使用,以及Redis的API操作。此外,还深入探讨了Redis的持久化机制,如RDB和AOF,以及如何通过主从复制和哨兵集群实现高可用性。最后,提到了Redis分片集群的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

非关系型数据数据库大量应用于数据缓存、消息队列等场景中,在大数据领域其非结构化特征与内存缓存数据的效果,适用于实时的数据分析,这里简单记录redis、hbase、kafka相关概念和使用


一、Redis基础

Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。其特点是启动时将数据加载至内存,可持久化数据,value数据类型丰富,本身可实现分布式、高可用。

1.Redis安装和配置

下载地址:https://download.redis.io/releases/ 或者wget https://download.redis.io/releases/redis-5.0.8.tar.gz

Redis是基于C语言编写的,因此首先需要安装Redis所需要的gcc依赖:
yum -y install gcc-c++ tcl
之后进行解压、编译、安装。
其主要配置为,log文件服务日志文件地址、datas文件持久化数据地址,

## 69行,配置redis服务器接受链接的网卡,表示任意机器都可以连接Redis服务
bind 0.0.0.0

## 136行,redis是否后台运行,设置为yes
daemonize yes

## 171行,设置redis服务日志存储路径
logfile "/export/server/redis/logs/redis.log"

## 263行,设置redis持久化数据存储目录
dir /export/server/redis/datas/

使用redis-server启动服务,使用redis-cli启动客户端

2.Redis简单操作

redis支持的数据类型有:
在这里插入图片描述
官方文档:https://redis.io/commands
客户端命令:help @generic

1、通用操作

  • keys:列举当前数据库中所有Key
    • 语法:keys 通配符
  • del key:删除某个KV
  • exists key :判断某个Key是否存在
    • 返回值:1,表示存在
    • 返回值:0,表示不存在
  • type key:判断这个K对应的V的类型的
  • expire K 过期时间:设置某个K的过期时间,一旦到达过期时间,这个K会被自动删除
  • ttl K:查看某个K剩余的存活时间
  • select N:切换数据库的
    • Redis默认由16个数据:db0 ~ db15,个数可以通过配置文件修改,名称不能改

    • Redis是一层数据存储结构:所有KV直接存储在数据库中

    • 默认进入db0

  • flushdb:清空当前数据库的所有Key
  • flushall:清空所有数据库的所有Key
    在这里插入图片描述

2、String类型操作

  • set:给String类型的Value的进行赋值或者更新
    • 语法:set K V
  • get:读取String类型的Value的值
    • 语法:get K
  • mset:用于批量写多个String类型的KV
    • 语法:mset K1 V1 K2 V2 ……
  • mget:用于批量读取String类型的Value
    • 语法:mget K1 K2 K3 ……
  • setnx:只能用于新增数据,当K不存在时可以进行新增
    • 语法:setnx K V
  • incr:用于对数值类型的字符串进行递增,递增1,一般用于做计数器
    • 语法:incr K
  • incrby:指定对数值类型的字符串增长固定的步长
    • 语法:incrby K N
  • decr:对数值类型的数据进行递减,递减1
    • 语法:decr K
  • decrby:按照指定步长进行递减
    • 语法:decrby K N
  • incrbyfloat:基于浮点数递增
    • 语法:incrbyfloat K N
  • strlen:统计字符串的长度
    • 语法:strlen K
  • getrange:用于截取字符串
    • 语法:getrange s2 start end,包头包尾
      在这里插入图片描述

3、Hash类型操作

Hash相当于表形式,将字典类型的数据按列进行分区,通过field获取

  • hset:用于为某个K添加一个属性

    • 语法:hset K k v
  • hget:用于获取某个K的某个属性的值

    • 语法:hget K k
  • hmset:批量的为某个K赋予新的属性

    • 语法:hmset K k1 v1 k2 v2 ……
  • hmget:批量的获取某个K的多个属性的值

    • 语法:hmget K k1 k2 k3……
  • hgetall:获取所有属性的值

    • 语法:hgetall K
  • hdel:删除某个属性

    • 语法:hdel K k1 k2 ……
  • hlen:统计K对应的Value总的属性的个数

    • 语法:hlen K
  • hexists:判断这个K的V中是否包含这个属性

    • 语法:hexists K k
  • hvals:获取所有属性的value的

    • 语法:hvals K
      在这里插入图片描述

4、List类型操作

redis中的list类型相当于java中的linkedlist即双向链表,其特点是便于修改、添加、删除,不便于查询

  • lpush:将每个元素放到集合的左边,左序放入

    • 语法:lpush K e1 e2 e3……
  • rpush:将每个元素放到集合的右边,右序放入

    • 语法:rpush K e1 e2 e3……
  • lrange:通过下标的范围来获取元素的数据

    • 语法:lrange K start end

    • 注意:从左往右的下标从0开始,从右往左的下标从-1开始,一定是从小的到大的下标

    • lrange K 0 -1:所有元素

  • llen:统计集合的长度

    • 语法:llen K
  • lpop:删除左边的一个元素

    • 语法:lpop K
  • rpop:删除右边的一个元素

    • 语法:rpop K
      在这里插入图片描述

5、Set类型操作

set集合类型类似于hashset,无序、不重复、查找快、支持交集、并集、差集等操作

  • sadd:用于添加元素到Set集合中

    • 语法:sadd K e1 e2 e3 e4 e5……
  • smembers:用于查看Set集合的所有成员

    • 语法:smembers K
  • sismember:判断是否包含这个成员

    • 语法:sismember K e1
  • srem:删除其中某个元素

    • 语法:srem K e
  • scard:统计集合长度

    • 语法:scard K
  • sunion:取两个集合的并集

    • 语法:sunion K1 K2
  • sinter:取两个集合的交集

    • 语法:sinter K1 K2
      在这里插入图片描述

6、SortSet类型操作

SortSet有序集合,其中有默认score属性,可利用其对集合排序,不重复、查询快

  • zadd:用于添加元素到Zset集合中

    • 语法:zadd K score1 k1 score2 k2 ……
  • zrange:范围查询

    • 语法:zrange K start end [withscores]
  • zrevrange:倒序查询

    • 语法:zrevrange K start end [withscores]
  • zrem:移除一个元素

    • 语法:zrem K k1
  • zcard:统计集合长度

    • 语法:zcard K
  • zscore:获取评分

    • 语法:zscore K k
      在这里插入图片描述

3.Redis Api操作

利用maven导入redis依赖

<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>3.2.0</version>
</dependency>

建立连接

// 建立连接
Jedis jedis = new Jedis("127.0.0.1", 6379);
// 选择库
jedis.select(0);

释放资源

// 释放资源
if (jedis != null) {
  jedis.close();
}

测试代码

public class JedisApiTest {

	// 定义Jedis变量
	private Jedis jedis = null ;

	@Before
	public void open(){
		// TODO: step1. 获取连接
		jedis = new Jedis("127.0.0.1", 6379);
	}

	@Test
	public void testString() throws Exception{
		// TODO: step2. 使用连接,操作Redis数据,数据类型为String
		/*
			set/get/exists/expire/ttl
		 */
		jedis.set("name","Jack");
		System.out.println(jedis.get("name"));

		System.out.println(jedis.exists("name"));
		System.out.println(jedis.exists("age"));

		jedis.expire("name",10);
		Long ttl = -1L ;
		while(-2 != ttl){
			ttl = jedis.ttl("name") ;
			System.out.println("ttl = " + ttl);

			TimeUnit.SECONDS.sleep(1);
		}
	}


	@After
	public void close(){
		// TODO: step3. 关闭连接
		if(null != jedis) jedis.close();
	}
}

Jdeis Poll连接池,数据库连接池,减少频繁的创建和销毁连接

public class JedisPoolTest {

	// 定义Jedis变量
	private Jedis jedis = null ;

	// 初始化
	@Before
	public void open(){
		// TODO: step1. 获取连接
		// 1-1. 配置
		JedisPoolConfig config = new JedisPoolConfig();
		// 连接池中总的连接数
		config.setMaxTotal(8);
		// 表示连接池中最小有几个连接空闲
		config.setMinIdle(3);
		// 表示连接池最多有几个连接空闲
		config.setMaxIdle(8);
		// 1-2. 连接池
		JedisPool jedisPool = new JedisPool(config, "127.0.0.1", 6379) ;
		// 1-3. 获取连接
		jedis = jedisPool.getResource();
	}


	@Test
	public void testString(){
		/*
			set/get/exists/expire/ttl
		 */
		jedis.set("name", "Lucy");
		System.out.println(jedis.get("name"));

		System.out.println("name exists: " + jedis.exists("name"));
		System.out.println("age exists: " + jedis.exists("age"));

		jedis.expire("name", 10);
		System.out.println(jedis.ttl("name"));
	}


	@After
	public void close(){
		// TODO: step3. 关闭连接,释放资源
		if(null != jedis) jedis.close();
	}

}

二、Redis集群

1.Redis 单点问题

在这里插入图片描述

redis 持久化RDB持久化

RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中

  • 当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。
  • 快照文件称为RDB文件,默认是保存在当前运行目录。
  • RDB持久化在四种情况下会执行:
    • 执行save命令
    • 执行bgsave命令
    • Redis停机时
    • 触发RDB条件时

save与bgsave的区别在于,save命令会导致主进程执行RDB,这个过程中其它所有命令都会被阻塞。只有在数据迁移时可能用到。
bgsave会开启独立进程完成RDB,主进程可以持续处理用户请求,不受影响。
停机时save会自动触发
同时在redis.conf可以配置save触发条件和是否开启压缩:

# 900秒内,如果至少有1个key被修改,则执行bgsave , 如果是save "" 则表示禁用RDB
save 900 1  
save 300 10  
save 60 10000 

# 是否压缩 ,建议不开启,压缩也会消耗cpu,磁盘的话不值钱
rdbcompression yes

# RDB文件名称
dbfilename dump.rdb  

# 文件保存的路径目录
dir ./ 

bgsave开始时会fork主进程得到子进程,子进程共享主进程的内存数据。完成fork后读取内存数据并写入 RDB 文件。
fork采用的是copy-on-write技术:

  • 当主进程执行读操作时,访问共享内存;
  • 当主进程执行写操作时,则会拷贝一份数据,执行写操作。

redis 持久化AOF持久化

AOF全称为Append Only File(追加文件)。Redis处理的每一个写命令都会记录在AOF文件,可以看做是命令日志文件。
默认关闭。可通过redis.conf开启

# 是否开启AOF功能,默认是no
appendonly yes
# AOF文件的名称
appendfilename "appendonly.aof"

# 表示每执行一次写命令,立即记录到AOF文件
appendfsync always 
# 写命令执行完先放入AOF缓冲区,然后表示每隔1秒将缓冲区数据写到AOF文件,是默认方案
appendfsync everysec 
# 写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘
appendfsync no

在这里插入图片描述
RDB和AOF各有自己的优缺点,如果对数据安全性要求较高,在实际开发中往往会结合两者来使用。
在这里插入图片描述

2.Redis 主从复制集群

单纯提高集群的并发能力,设置多态服务器,主节点为master,从介节点为salve
主要配置为:

replica-announce-ip

slaveof <masterip> <masterport>

3.Redis 哨兵集群

解决主从集群单点故障问题,实现自动故障转移,通过频繁的ping pong实现。

Redis提供了哨兵(Sentinel)机制来实现主从集群的自动故障恢复,哨兵的结构和作用如下:

  • 监控 :Sentinel 会不断检查您的master和slave是否按预期工作
  • 自动故障恢复:如果master故障,Sentinel会将一个slave提升为master
  • 通知:Sentinel充当Redis客户端的服务发现来源,当集群发生故障转移时,将最新信息推送给Redis的客户端

Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令:

  • 主观下线:如果某sentinel节点发现某实例未在规定时间响应,则认为该实例主观下线
  • 客观下线:若超过指定数量(quorum)的sentinel都认为该实例主观下线,则该实例客观下线。quorum值最好超过Sentinel实例数量的一半。
  • sentinel给备选的slave1节点发送slaveof no one命令,让该节点成为master
  • sentinel给所有其它slave发送slaveof 命令,让这些slave成为新master的从节点,开始从新的master上同步数据。
  • 最后,sentinel将故障节点标记为slave,当故障节点恢复后会自动成为新的master的slave节点

4.Redis 分片集群

通过多个集群集成,实现数据分布式存储,高并发写,海量数据存储

  • 集群中有多个master,每个master保存不同数据
  • 每个master都可以有多个slave节点
  • master之间通过ping监测彼此健康状态

客户端请求可以访问集群任意节点,最终都会被转发到正确节点
每个小集群分摊一部分槽位Slot,对每一条Redis的数据进行槽位计算,这条数据属于哪个槽位,就存储对应槽位的小集群中
根据Key进行槽位运算:CRC16[K] & 16383 = 0 ~ 16383

5.Redis 集群API

public class JedisClusterTest {

	public static void main(String[] args) {
		// TODO: 1. 获取连接
		// 1-1. 连接池设置
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxTotal(8); // 连接池中总的连接数
		config.setMaxIdle(5); // 连接池中最大连接空闲数,连接未被使用数目
		config.setMinIdle(2); // 连接池中最小连接空闲数
		config.setMaxWaitMillis(5000); // 最大等待时间
		// 1-2. 集群地址和端口号
		HashSet<HostAndPort> set = new HashSet<>() ;
		set.add(new HostAndPort("node1",7001));
		set.add(new HostAndPort("node1",7002));
		set.add(new HostAndPort("node2",7001));
		set.add(new HostAndPort("node2",7002));
		set.add(new HostAndPort("node3",7001));
		set.add(new HostAndPort("node3",7002));

		// 1-3. 获取连接
		JedisCluster jedisCluster = new JedisCluster(set, 2000, 2000, 5, config);

		// TODO: 2. 使用连接,操作数据
		jedisCluster.set("name", "zhangsan");
		System.out.println(jedisCluster.get("name"));

		// TODO: 3. 关闭连接
		jedisCluster.close();
	}

}

总结

Redis简单应用。
时光如水,人生逆旅矣。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值