Redis Stream:更完善的消息队列

该数据结构需要 Redis 5.0.0 + 版本才可用使用 概述 Redis stream 是 Redis 5 引入的一种新的数据结构,它是一个高性能、高可靠性的消息队列,主要用于异步消息处理和流式数据处理。在此之前,想要使用 Redis 实现消息队列,通常可以使用例如:列表,有序集合、发布与订阅 3 种数据结构。但是 stream 相比它们具有以下的优势: 支持范围查找:内置的索引功能,可以通过索引来对消息进行范围查找 支持阻塞操作:避免低效的反复轮询查找消息 支持 ACK:可以通过确认机制来告知已经成功处理了消息,保证可靠性 支持多个消费者:多个消费者可以同时消费同一个流,Redis 会确保每个消费者都可以独立地消费流中的消息 话不多说,接下来具体看看如何使用它。(PS:万字长文,行驶途中请系好安全带) XADD 添加元素 XADD 命令的语法格式如下: XADD stream-name id field value [field value] stream-name: 指定 redis stream 的名字 id: 是指 stream 中的消息 ID,通常使用 * 号表示自动生成 field value: 就是消息的内容,是 K-V 格式的键值对 关于使用 XADD 添加元素,还有以下特点: 自动创建流:当 my-stream 流不存在时,redis 会自动创建,然后将元素追加在流的末尾处 任意键值对:流中的每个元素可以包含一个或任意多个键值对 下面是一个使用 XADD 命令添加新消息的示例: XADD my-stream * name John age 30 email john@example.com 上述命令的说明: ...

April 17, 2023 · 8 min

关系型数据库的基本设计原则

前言 工作的这些年发现一个比较奇怪的现象就是身边无论是工作十多年的老兵,还是初级刚入行的程序员,在高谈阔论技术和趋势的时候都是人工智能,大数据,区块链,各种框架,语言,算法,AI,BI,CI,DI…… 等等,倒是发现很少有人关注数据库,不知道是因为数据库感觉太低端还是太低调,总是不容易被人提起 技术就是这样,不太关注的地方就不会重视,越是不被重视的地方,掉进坑里的概率就会越大,所以就在这里给大家简单聊聊在使用数据库过程中有哪些防掉坑指南,也可以对刚入行的小朋友有一个提醒的作用,万丈高楼平地起,一定要先打好基础再去考虑上层的建筑,不要舍本逐末 本章主要分以下四个小节(预计读完 5 分钟左右): 数据库为什么重要 数据库有哪些使用技巧 数据库有哪些容易掉进去的坑? 深入学习数据库的建议 数据库为什么重要 很多人在开发过程中不太关注数据库,对于表结构的设计也没什么讲究大多属于“能用就行”,但是根据作者将近十年的开发经验来看的话,只要你是从事 Web 相关领域开发你就无法避免不和数据库打交道,在Web开发中大多功能操作本质上都是对数据库进行操作,不管你用是 Pythod,Java,Ruby 等语言进行 Web 开发,你其实都是在面向数据库进行编程,很多 Web 框架作者为了避免程序员接触数据库的相关知识甚至还封装了一层 ORM (Object Relational Mapping 对象关系映射),把数据库当做一个黑盒子,然后通过操作对象的形式来操作数据库 虽然某种意义上是简化的开发,对此我是持有保留意见的,因为对于程序员来说很有必要了解你的 SQL 语言在数据库是怎么执行的,你不仅需要使用 explain 执行计划来查看你的 SQL 是否高效(扫描行数,命中索引,回表,排序等),对比不同 SQL 的写法外,你还需要知道如何使用 show index 来查看你的索引是否高效(通过 Cardinality 由数据库评估),这些技巧很大程度依赖你对 SQL 的了解,SQL 对于程序员来说也是一门非常重要的技能,没错 SQL 就是操作数据库的语言,据我了解大多数的公司在面试的时候都会考察程序员的 SQL 功底,扎实的 SQL 功底不仅可以让你写出高性能的查询语言外,对于数据分析,报表统计也是有非常大的帮助 大多数商业公司的核心资产其实就是数据库里面的数据,是非常宝贵的财富,程序和系统挂了,最多就是一段时间不可用,大多是情况重启就可以恢复,但是是数据库不小心被误删了,如果是运维能力差的中小企业可能会面临倒闭的地步,从商业角度上来说数据库大多数软件公司的核心 很多程序员从菜鸟成长到高手,接触的项目从学校的"某某管理系统"到刚加入公司内部系统,然后再到大型分布式系统,在大型系统中,大多数人程序员通常遇到的第一个问题通常不是线程不够用,不是CPU负载过高,不是内存不够快,通常都是数据库扛不住压力了,为什么呢?数据库本身就基于磁盘的文件系统,每次读取数据都是通过 I/O 去访问磁盘,了解计算机原理的同学应该都知道,在冯诺依曼计算机体系结构里磁盘 I/O 号称是最慢的 I/O (毫秒级),通常在你的系统只有几千上万的数据量时,全表扫描通常不会有很大的延迟感,但是当你的存量数据达到百万千万时,那么一次普通的查询就会把你的数据库服务器撑爆,做过应用的人都知道,数据库挂了,不管是什么分布式,微服务的牛逼架构都基本没啥用了,唠唠叨叨说到这里,相信大家应该已经知道数据库的重要性的,后面我们再从数据库设计的角度来看下问题 数据库设计对系统的影响 这里我们简单做一个对比,良好的数据库设计可以为你带来什么 ? 减少数据冗余,避免数据维护异常 节省存储空间,高效的访问速度 糟糕的设计 ? 大量数据冗余插入,更新,删除异常 浪费存储空间,低效的访问速度 糟糕的设计(图) 比如说对于一个简单的年龄字段,严谨来说应该使用 tinyint(1字节)或者 smallint(2字节),但是你偏偏要用 int (4字节) 这就属于糟糕的字段选择,看到这里很多刚入门的同学就可能就会反驳了,这么在意空间利用是不是有点矫枉过正?包括存储已经很便宜了,还这么斤斤计较般的选择,反正最终实现的功能都是相同的,别人也看不出什么差别呀。对于这种观点其实我想反驳一下,这是典型的新手思维,你只在看到在单个字段上的空间节省,但是没有考虑过数据也是在持续增长,糟糕的设计越到后期增长成本会越高(这里就类似于 Java 的经典面试题,集合类 ArrayList 和 LinkedList 在少量数据对比时看不出时间上的差距,但是随着计算数据量的上升,消耗数据的差距也会越拉越大),等到了千万级数据量的时候,可能你设计的表和别人设计的表是相同的内容,但是你的表无端的多出几百G的存储空间,如果你的应用还是多数据中心的话,那么这种无端的空间浪费还会被拷贝几十倍到不同的数据中心,而且只要你的应用还在线上运行,那么这种增长所带来的成本还会持续上升,这里也仅仅只是说对空间的浪费,下面在分析表结构存储上,还会具体说一下糟糕的设计对于性能会有多大的影响,这对企业来说就是边际成本的递增,从技术和架构上来说就会让你的系统不具备可扩展性 ...

February 27, 2020 · 2 min