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

素材天下网站惠州网站建设行业

素材天下网站,惠州网站建设行业,网站建设 微信微博外包,建站登录title: redis基础结构 date: 2025-03-04 08:39:12 tags: redis categories: redis笔记 Redis入门 #xff08;NoSQL, Not Only SQL#xff09; 非关系型数据库 关系型数据库#xff1a;以 表格 的形式存在#xff0c;以 行和列 的形式存取数据#xff0c;一系列的行和列被… 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 采用 epollLinux或 selectWindows 作为 IO 多路复用技术主要使用 aeEventLoop 事件处理机制 主线程通过 epoll/select/kqueue 监听多个客户端连接当某个连接有数据可读如命令请求Redis 触发相应的回调函数回调函数读取请求处理命令返回结果继续监听新的请求不会阻塞在某个请求上 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类型 KeyValueblog: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字符串最基本的数据结构可以存储字符串、整数或浮点数SET、GET、INCR、DECR、APPEND、MSET、MGETSET key valueGET keyList列表有序集合允许重复元素底层为双向链表LPUSH、RPUSH、LPOP、RPOP、LRANGELPUSH mylist A B CLRANGE mylist 0 -1Set集合无序集合不允许重复元素SADD、SREM、SMEMBERS、SISMEMBERSADD myset A B CSMEMBERS mysetHash哈希类似于对象存储键值对HSET、HGET、HGETALL、HDELHSET user name AliceHGET user nameZSet有序集合具有权重score的集合元素按分数排序ZADD、ZRANGE、ZREM、ZSCOREZADD myzset 1 A 2 BZRANGE myzset 0 -1Bitmap位图位级别的存储用于高效存储和操作二进制数据SETBIT、GETBIT、BITCOUNTSETBIT mybitmap 10 1GETBIT mybitmap 10HyperLogLog近似去重计数结构适用于大数据计数PFADD、PFCOUNTPFADD myhll A B CPFCOUNT myhllGeo地理位置存储经纬度并计算地理距离GEOADD、GEODIST、GEORADIUSGEOADD mygeo 120.0 30.0 place1GEODIST mygeo place1 place2Stream流可持久化的消息队列结构XADD、XLEN、XREADXADD mystream * name AliceXREAD COUNT 1 STREAMS mystream 0 这些结构和指令在不同的应用场景中有不同的优势比如 String 适用于缓存数据List 适用于消息队列Set 适用于去重ZSet 适用于排行榜Hash 适用于存储对象Bitmap 适用于用户签到或活跃记录HyperLogLog 适用于大规模数据去重统计Geo 适用于地理位置存储Stream 适用于事件流和消息队列。 java客户端连接redis 使用Jedis 1.导入依赖 dependencygroupIdredis.clients/groupIdartifactIdjedis/artifactIdversion3.8.0/version /dependency2.建立连接 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依赖--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependency!--连接池依赖--dependencygroupIdorg.apache.commons/groupIdartifactIdcommons-pool2/artifactId/dependency2.配置连接信息 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);MapString, 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\x02v1RedisTemplate 存在的问题 通过以上操作可以发现RedisTemplate 可以将任意类型的数据写入到 Redis 中在写入前会将其序列化为字节形式存储底层默认采用 ObjectOutputStream 序列化。 4.因此我们要重写他的序列化工具 导入 jackson-databind 依赖并编写配置类 RedisTemplateConfig。 Configuration public class RedisTemplateConfig {Beanpublic RedisTemplateString, Object redisTemplate(RedisConnectionFactory redisConnectionFactory) {// 创建 RedisTemplate 对象RedisTemplateString, Object redisTemplate new RedisTemplate();// 设置连接工厂redisTemplate.setConnectionFactory(redisConnectionFactory);// 设置序列化工具GenericJackson2JsonRedisSerializer jsonRedisSerializer new GenericJackson2JsonRedisSerializer();// Key 和 HashKey 采用 String 序列化StringRedisSerializerredisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setHashKeySerializer(RedisSerializer.string());// Value 和 HashValue 采用 JSON 序列化GenericJackson2JsonRedisSerializerredisTemplate.setValueSerializer(jsonRedisSerializer);redisTemplate.setHashValueSerializer(jsonRedisSerializer);return redisTemplate;} }// 自动注入的 RedisTemplate 需要加上泛型 Autowired private RedisTemplateString, 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 对象时手动完成对象的序列化和反序列化。 使用 StringRedisTemplate。写入数据到 Redis 中手动将对象序列化为 JSON。从 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.w-s-a.com/news/658560/

相关文章:

  • 网站做a视频在线观看网站天津建站
  • 自己做的网站怎么链接火车头采集一个网站可以做几级链接
  • 济南网站制作哪家专业做网站怎样投放广告
  • 辽宁网站推广短视频运营培训学费多少
  • 拼多多网站怎么做翻译 插件 wordpress
  • 做网站运营的职业生涯规划wordpress分类显示图片
  • 网站建设与制作总结沈阳百度广告
  • 网站管理系统 手机会员制网站搭建wordpress
  • 做物品租赁网站清新wordpress主题
  • 优秀专题网站家居企业网站建设市场
  • 中山市有什么网站推广wordpress轻应用主机
  • 洗头竖鞋带名片改良授权做网站不贵整个世界
  • 设计电子商务网站建设方案微信如何开发自己的小程序
  • 建设网站公司哪里好相关的热搜问题解决方案做网站要看什么书
  • 网站建设重要性黄岐建网站
  • 做网站电销《电子商务网站建设》精品课
  • 地方商城网站海外网站推广方法
  • 乐山 网站建设安阳给商家做网站推广
  • 网站空间一般多大邢台网站建设有哪些
  • h5网站开发工具有哪些wordpress清空post表
  • 公司开网站干嘛怎么制作一个免费的网站模板
  • 群晖wordpress搭建网站网站建设及管理
  • 中山企业网站建设公司抖音代运营合作模式
  • 南通营销网站开发做网站页面多少钱
  • 桂林生活网官方网站云主机和云电脑的区别
  • 内部网络网站怎么做vue做单页面网站
  • 如何建立网站教程wordpress粘帖图片
  • 广东网站备案要多久网站开发 pdf 文字版
  • 学校网站方案帮别人做钓鱼网站吗
  • 如何加强网站建设和信息宣传wordpress 搜索提示