当前位置: 首页 > news >正文

网站空间ip地址项目推广计划书

网站空间ip地址,项目推广计划书,扬州网站建设开发,wordpress页脚主题信息隐藏title: redis基础结构 date: 2025-03-04 08:39:12 tags: redis categories: redis笔记 Redis入门 (NoSQL, Not Only SQL) 非关系型数据库 关系型数据库:以 表格 的形式存在,以 行和列 的形式存取数据,一系列的行和列被…

title: redis基础结构
date: 2025-03-04 08:39:12
tags: redis
categories: redis笔记

Redis入门

(NoSQL, Not Only SQL) 非关系型数据库

在这里插入图片描述

关系型数据库:以 表格 的形式存在,以 行和列 的形式存取数据,一系列的行和列被称为表,无数张表组成了 数据库。支持复杂的 SQL 查询,能够体现出数据之间、表之间的关联关系;也支持事务,便于提交或者回滚。

非关系型数据库:以 key-value 的形式存在,可以想象成电话本的形式,人名(key)对应电话号码(value)。不需要写一些复杂的 SQL 语句,不需要经过 SQL 的重重解析,性能很高;可扩展性也比较强,数据之间没有耦合性,需要新加字段就直接增加一个 key-value 键值对即可。

Redis 是 速度极快的、基于内存的,键值型 NoSQL 数据库。

为什么这么快?

  • 完全基于内存操作

  • 使用非阻塞的 IO 多路复用机制

  • 数据结构简单,对数据操作也简单。

  • 使用单线程,避免了上下文切换和竞争产生的消耗。

  • 支持多种数据类型,包括 String、Hash、List、Set、ZSet 等。

IO 多路复用机制

Redis 使用的是 IO 多路复用机制 来处理 高并发请求,这使得它能在 单线程 模式下仍然保持高吞吐量。


🔹 Redis 为什么要用 IO 多路复用?

  • Redis 是单线程的,但仍然能高效处理大量连接,这依赖于 IO 多路复用。
  • 传统的 阻塞 IO 方式,每次只能处理一个连接,性能受限。
  • 多路复用可以 同时监听多个客户端请求,只处理活跃连接,减少 CPU 空转。

🔹 Redis 的 IO 多路复用机制

Redis 采用 epoll(Linux)或 select(Windows) 作为 IO 多路复用技术,主要使用 aeEventLoop 事件处理机制

  1. 主线程通过 epoll/select/kqueue 监听多个客户端连接
  2. 当某个连接有数据可读(如命令请求),Redis 触发相应的回调函数
  3. 回调函数读取请求,处理命令,返回结果
  4. 继续监听新的请求,不会阻塞在某个请求上

Redis 使用 事件驱动模型,主要有:

  • 可读事件(AE_READABLE):当客户端有数据可读时触发。
  • 可写事件(AE_WRITABLE):当客户端可以写数据时触发。
  • 文件事件(File Event):通过 epoll 监听 多个 socket 连接
  • 时间事件(Time Event):用于定时任务(比如 key 过期检测)。

🔹 Redis 多路复用示意图

[多个客户端]│▼
[epoll/select 监听]│├── 客户端 A 可读 -> 触发回调 -> 读取数据├── 客户端 B 可写 -> 触发回调 -> 发送数据├── 客户端 C 可读 -> 触发回调 -> 读取数据│▼
[主线程执行 Redis 命令逻辑]

Redis的基础结构类型

Key结构

让 Redis 的 key 形成层级结构,使用 : 隔开:项目名:业务名:类型:id

set blog:user:1 '{"id":1, "name":"Jack", "age":22}'
set blog:user:2 '{"id":2, "name":"Mike", "age":23}'
set blog:article:1 '{"id":1, "title":"Spring"}'

String类型

KeyValue
blog:user:1‘{“id”:1, “name”:“Jack”, “age”:22}’
blog:user:2‘{“id”:2, “name”:“Mike”, “age”:23}’

分配策略:

Java 的 String 是不可变的,无法修改。Redis 的 String 是动态的,可以修改的。Redis 的 String 在内部结构实现上类似于 Java 的 ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。如图所示,当前字符串实际分配的空间为 capacity,一般高于实际的字符串长度 len。当字符串长度小于 1M 时,扩容是对现有空间的成倍增长;如果长度超过 1M 时,扩容一次只会多增加 1M 的空间。String 的最大长度为 512M。

在这里插入图片描述

Hash结构

在这里插入图片描述

list结构

List 类似 Java 中的 LinkedList,可以看作一个双向链表(有序可重复)。使用 List 可以对链表的两端进行 push 和 pop 操作、读取单个或多个元素、根据值查找或删除元素、支持正向检索和反向检索。

:LPUSH + LPOP 或 RPUSH + RPOP。

队列:LPUSH + RPOP 或 RPUSH + LPOP。

Set结构

SADD key member [member ...] :向 Set 中添加一个或多个元素。

SMEMBERS key :获取指定 Set 中的所有元素。

SISMEMBER key member :判断 Set 中是否存在指定元素。

SCARD key :返回 Set 中的元素个数。

SREM key member [member ...] :移除 Set 中的指定元素。

SINTER key [key ...] :求 n 个 key 间的交集。

SDIFF key [key ...] :求 n 个 key 间的差集。

SUNION key [key ...] :求 n 个 key 间的并集。

Redis 的 Set 类似 HashSet,可以看作一个 value 为 null 的 HashMap;其特征也与 HashSet 类似:无序不可重复,支持 交集、并集、差集等功能。

ZSet

Redis 的 ZSet 是一个可排序的 Set 集合,类似 ZSet。ZSet 的每一个元素都带有一个 score 属性,可以基于 score 属性对元素排序。

ZADD key [score member ...] :以 score 为权重向 ZSet 中添加一个或多个元素,如果存在则更新 score。

ZREM key member [member ...] :删除 ZSet 中的指定元素。

ZCARD key :返回 ZSet 中的元素个数。

ZSCORE key member :获取 ZSet 中指定元素的 score 值。

ZADD key [score member ...] :以 score 为权重向 ZSet 中添加一个或多个元素,如果存在则更新 score。

ZREM key member [member ...] :删除 ZSet 中的指定元素。

ZCARD key :返回 ZSet 中的元素个数。

ZSCORE key member :获取 ZSet 中指定元素的 score 值。

ZRANGEBYSCORE key min max :按照 score 排序后,获取 指定 score 范围 内的元素。

ZINTER numberKeys key [key ...] | ZDIFF numberKeys key [key ...] | ZUNION numberKeys key [key ...] :求 n 个 Zset 的交集、差集、并集。

Redis 基础结构及其操作指令总结

基础结构描述常用指令示例
String(字符串)最基本的数据结构,可以存储字符串、整数或浮点数SETGETINCRDECRAPPENDMSETMGETSET key valueGET key
List(列表)有序集合,允许重复元素,底层为双向链表LPUSHRPUSHLPOPRPOPLRANGELPUSH mylist A B CLRANGE mylist 0 -1
Set(集合)无序集合,不允许重复元素SADDSREMSMEMBERSSISMEMBERSADD myset A B CSMEMBERS myset
Hash(哈希)类似于对象,存储键值对HSETHGETHGETALLHDELHSET user name "Alice"HGET user name
ZSet(有序集合)具有权重(score)的集合,元素按分数排序ZADDZRANGEZREMZSCOREZADD myzset 1 A 2 BZRANGE myzset 0 -1
Bitmap(位图)位级别的存储,用于高效存储和操作二进制数据SETBITGETBITBITCOUNTSETBIT mybitmap 10 1GETBIT mybitmap 10
HyperLogLog近似去重计数结构,适用于大数据计数PFADDPFCOUNTPFADD myhll A B CPFCOUNT myhll
Geo(地理位置)存储经纬度并计算地理距离GEOADDGEODISTGEORADIUSGEOADD mygeo 120.0 30.0 "place1"GEODIST mygeo place1 place2
Stream(流)可持久化的消息队列结构XADDXLENXREADXADD mystream * name "Alice"XREAD COUNT 1 STREAMS mystream 0

这些结构和指令在不同的应用场景中有不同的优势,比如 String 适用于缓存数据,List 适用于消息队列,Set 适用于去重,ZSet 适用于排行榜,Hash 适用于存储对象,Bitmap 适用于用户签到或活跃记录,HyperLogLog 适用于大规模数据去重统计,Geo 适用于地理位置存储,Stream 适用于事件流和消息队列。

java客户端连接redis

使用Jedis

1.导入依赖

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

2.建立连接

public class JedisTest {private Jedis jedis;@BeforeEachvoid setUp(){//1.建立连接jedis = new Jedis("192.168.200.130",6379);//2.设置密码jedis.auth("1234");//3.选择库jedis.select(0);}@Testvoid testString(){String result = jedis.set("name", "小明");System.out.println("result= " + result);String name = jedis.get("name");System.out.println("name= "+name);}@AfterEachvoid tearDown(){if(jedis!=null){jedis.close();}}}

3.jedis连接池

public class JedisConnectFactory {private static final JedisPool jedisPool;static{//配置连接池JedisPoolConfig poolConfig = new JedisPoolConfig();poolConfig.setMaxTotal(8);poolConfig.setMaxIdle(8);poolConfig.setMinIdle(0);poolConfig.setMaxWait(Duration.ofMillis(1000));jedisPool = new JedisPool(poolConfig,"192.168.200.130",6379,1000,"1234");}public static Jedis getJedis(){return jedisPool.getResource();}}

1) JedisConnectionFacotry:工厂设计模式是实际开发中非常常用的一种设计模式,我们可以使用工厂,去降低代的耦合,比如Spring中的Bean的创建,就用到了工厂设计模式

2)静态代码块:随着类的加载而加载,确保只能执行一次,我们在加载当前工厂类的时候,就可以执行static的操作完成对 连接池的初始化

3)最后提供返回连接池中连接的方法.

使用springDataRedis连接

在这里插入图片描述

1.导入依赖

        <!--Redis依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--连接池依赖--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency>

2.配置连接信息

spring:redis:host: 192.168.200.130port: 6379password: 1234database: 0lettuce:pool:max-active: 8 #最大连接数max-idle: 8 #最大空闲连接min-idle: 0 #最小空闲连接max-wait: 100 #连接等待时间

3.直接注入RedisTemplate出现的问题

// 自动注入的 `RedisTemplate` 需要加上泛型
@Resource
private RedisTemplate redisTemplate;@Test
public void test() {redisTemplate.opsForValue().set("k1", "v1");Map<String, String> map = new HashMap<>();map.put("k2", "v2");map.put("k3", "v3");map.put("k4", "v4");map.put("k5", "v5");redisTemplate.opsForValue().multiSet(map);redisTemplate.opsForValue().multiGet(Arrays.asList("k1", "k2", "k3", "k4")).forEach(System.out::println);  // v1 v2 v3 v4 v5
}//结果
# 在 Redis 中查看通过 RedisTemplate 插入的数据
> keys *
1) "\xac\xed\x00\x05t\x00\x02k1"
2) "\xac\xed\x00\x05t\x00\x02k2"
3) "\xac\xed\x00\x05t\x00\x02k3"
4) "\xac\xed\x00\x05t\x00\x02k4"
5) "\xac\xed\x00\x05t\x00\x02k5"> get "\xac\xed\x00\x05t\x00\x02k1"
"\xac\xed\x00\x05t\x00\x02v1"

RedisTemplate 存在的问题

通过以上操作可以发现:RedisTemplate 可以将任意类型的数据写入到 Redis 中,在写入前会将其序列化为字节形式存储,底层默认采用 ObjectOutputStream 序列化。

4.因此我们要重写他的序列化工具

导入 jackson-databind 依赖,并编写配置类 RedisTemplateConfig

@Configuration
public class RedisTemplateConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {// 创建 RedisTemplate 对象RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();// 设置连接工厂redisTemplate.setConnectionFactory(redisConnectionFactory);// 设置序列化工具GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();// Key 和 HashKey 采用 String 序列化(StringRedisSerializer)redisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setHashKeySerializer(RedisSerializer.string());// Value 和 HashValue 采用 JSON 序列化(GenericJackson2JsonRedisSerializer)redisTemplate.setValueSerializer(jsonRedisSerializer);redisTemplate.setHashValueSerializer(jsonRedisSerializer);return redisTemplate;}
}
// 自动注入的 `RedisTemplate` 需要加上泛型
@Autowired
private RedisTemplate<String, Object> redisTemplate;@Test
public void test() {redisTemplate.opsForValue().set("k1", "v1");redisTemplate.opsForValue().set("user:1", new User("Jack", 21));
}

通过以上的方法能够解决数据序列化时 可读性差、内存占用大 的问题。

但是 JSON 的序列化方式仍然存在一些问题:为了反序列化时知道对象的类型,JSON 序列化器会将类的 class 类型写入 JSON 结果,存入 Redis 中,会带来额外的内存开销。

5.使用StringRedisTemplate

为了节省内存空间,Spring 提供了一个 StringRedisTemplate,它的 key 和 value 的序列化方式默认就是 String,统一使用 String 序列化器。

当需要存储 Java 对象时,手动完成对象的序列化和反序列化。

  1. 使用 StringRedisTemplate。
  2. 写入数据到 Redis 中,手动将对象序列化为 JSON。
  3. 从 Redis 中读取数据,手动将读取到的 JSON 反序列化为对象。
@Autowired
private StringRedisTemplate stringRedisTemplate;private static final ObjectMapper objectMapper = new ObjectMapper();@Test
public void ttt() throws JsonProcessingException {User user = new User("Michael", 27);// 手动序列化String json = objectMapper.writeValueAsString(user);// 写入数据stringRedisTemplate.opsForValue().set("user:1", json);// 读取数据String data = stringRedisTemplate.opsForValue().get("user:1");// 反序列化User deserializedUser = objectMapper.readValue(data, User.class);System.out.println(deserializedUser);
}
//结果
{"username": "Michael","age": 27
}
http://www.mmbaike.com/news/86715.html

相关文章:

  • 如何做公证网站网页发布时间百度云电脑版网站入口
  • 网站建设推广人员北京疫情太严重了
  • 网站设计论文总结关键词营销推广
  • 去什么网站做推广地推推广平台
  • 平台网站模板素材全球网络营销公司排行榜
  • 内网穿透做网站能查到网站ip吗淘宝的17种免费推广方法
  • 电商网站建设c微fzsszai百度一下百度下载
  • 网站不备案什么意思搜索百度app下载
  • 网站建设解决方案湖南网络营销外包
  • 怎么查看网站是哪个公司做的万能bt搜索引擎
  • wordpress七牛远程图片合肥seo排名优化公司
  • 创建网站目录权限论坛企业推广
  • 深圳做购物网站seo推广优化
  • 如何做服装微商城网站建设百度推广助手
  • wordpress app 源码百度免费seo
  • 网站开发的技术意义网站推广排名哪家公司好
  • 深圳工作服制作杭州谷歌seo公司
  • 做一个动态网站要多少钱百度收录提交申请网站
  • wordpress 地址转换上海关键词排名手机优化软件
  • 做品牌网站南宁seo关键词排名
  • dedecms手机网站网站设计与实现毕业设计
  • 邓州网站设计武汉企业网站推广
  • 谁有哪种浏览器网站免费的关键词排名优化软件价格
  • 注册公司后才可以做独立网站吗南京百度关键字优化价格
  • 做黏土的网站b站视频未能成功转码
  • 网站如何做微信支付宝支付宝支付宝接口百度下载安装到桌面上
  • 昆明快速建站模板百度总部在哪里
  • 网站建设报价企业查询系统
  • wordpress自动评论插件杭州企业seo
  • 政府网站建设经费 报告南京seo外包