Redis数据结构
😀 这里写文章的前言:Redis的8大数据结构: String,List,Map,Set,ZSet,bitmaps,hperloglogs,geoRedis是C++写的,C的很多操作不是很高效,比如, C传统的字符串需要遍历整个长度得到一个长度,与Redis的高效是不符合的,所以需要自己设计一些数据结构
📝 动态字符串(SDS)
c语言的字符串频繁修改一个字符串时,会涉及到内存的重分配,比较消耗性能
Redis中的动态字符串就是利用free和len字段,采用内存预分配和惰性空间释放
空间预分配: 减少修改字符串带来的内存重分配的次数,sds采用一次管够的策略,会多分配一些内存;比如上图的capacity就是实际分配的内存,会比字符串的长度要多
惰性空间释放:对字符串进行缩短操作时,程序不立刻使用内存重新分配回收缩短后多余的字节,而是使用free属性将这些字节的数量记录下来,等待后续使用
Redis的SDS API是安全的,拼接字符串不会造成缓冲区溢出。SDS在拼接字符串之前会检查SDS空间是否满足需求,如果空间不够会自动扩容,所以不会导致缓冲区溢出的问题
SDS获取字符 ...
Redis的过期策略和内存淘汰
😀 这里写文章的前言:Redis的过期删除和内存淘汰策略
📝 过期删除策略Redis的过期删除策略有3种
惰性删除
定期删除
定时删除
惰性删除是指⼀个 key 过期后,并不会直接删除,⽽是等到该 key 被再次访问时,才执⾏删除
惰性删除对内存不友好,但是对cpu很友好。只有到key被访问了,我们才会去先判断key是否过期,过期就直接删除key,并返回nil。但是如果有key长时间没有被访问到,内存就会一直被占用
Redis在访问或者修改Key之前,都会调用expireIfNeeded函数对其进行检查,检查Key是否过期:
如果过期,则删除该 key,至于选择异步删除,还是选择同步删除,根据 lazyfree_lazy_expire 参数配置决定(Redis 4.0版本开始提供参数),然后返回 null 客户端
如果没有过期,不做任何处理,然后返回正常的键值对给客户端
redis的惰性删除策略由db.c文件中的 expireIfNeeded 实现:
int expireIfNeeded(redisDb *db, robj *key) {//判断 key ...
数据开发经历(二)
😀 这里写文章的前言:一个简单的开头,简述这篇文章讨论的问题、目标、人物、背景是什么?并简述你给出的答案。
可以说说你的故事:阻碍、努力、结果成果,意外与转折。
📝 数据开发流程 其实数据开发中遇见的问题和我们应用层面的问题存在部分的相似之处,但是在进行数据问题排错的时候,又存在些许的不相似。总体上的感觉,得去做过和排查过,自身才能对问题理解到比较清晰
任务调度 任务调度,这个是有时序的,也是存在先后顺序的。 一般最晚的时间点就是我们拉取最晚那批数据的时间了。
理想情况下(基于离线数仓): 比较理想的情况下,就是我们最好每一层的处理时间预算都是停留在一个小时左右,但是具体的时间量等情况,得看数据量和具体的业务需要了.
0点1点: 执行ods的数据,具体的调度周期就跟你业务上的数据变化或者数仓中的数据需要,来进行调度周期是天/周/月等情况的调度处理.
1点到2点: 执行dim或者dwd的数据,这个组织维度的数据,看是否有变化的调整(一般公司的人员组织或者集团下的预取,城市,项目之类的会存在有变化的调整).
2点到3点: dws 层的数据处理,一般d ...
Redis存储原理和持久化
😀 这里写文章的前言:Redis的存储和持久
📝 Redis存储原理📔数据库Redis服务端一般有16个数据库,默认情况下都在0号数据库操作,我们也可以通过命令来实现数据库的切换 –select 1-16 命令
对数据库的增删改查,本质上就是通过客户端指向的数据库,查找里面的字典,匹配对应的key,取出对应的value
📔字典表 dict每个数据库都有一个字典结构,这个字典里存着两个hash表(为了之后的扩缩容)
整体使用了一个大的 hash 表, 因为 hash 能够尽可能的提供 O1 时间复杂度的效率
而这个hash表里有一个dictEntry 组成的数组,里面存放的就是所有的键值对。这个dictEntry还有指向下一个节点的指针,就是为了在hash冲突的情况,采用拉链法扩展出一个链表
向字典表再添加一个元素 set name xxx我们会先对key做散列运算,将得到的值再对哈希表的大小做一个取余,假设得到的值是1,那么这个key就会落在1的位置,如果多个元素都落在同一个元素,就会形成一个链表,比如:
字典表属性解读
table: 键值对哈希表,用于保存数据库 ...
数据开发经历(一)
😀 这里写文章的前言:一个简单的开头,简述这篇文章讨论的问题、目标、人物、背景是什么?并简述你给出的答案。
可以说说你的故事:阻碍、努力、结果成果,意外与转折。
📝 简介 在公司的数据平台上,进行一些简单的指标开发也有一段时间了,对于是否有预期的成长的还是取决于个人的欲望以及行动,不排除我是行动的巨婴.
也简单的记录下自己这段时间的一些总结语录以及如果我下次还在数据方面的项目上怎么处理?
需求和调研 由于目前的项目都是在乙方的场景,所以需要去与甲方进行沟通了解他们的需求以及系统,并且同时还要去推动相关需求指标的进度。这里涉及到的东西其实很多。
需求以及调研: 这个阶段一定要好好梳理该对行业或者同样类似的系统,进行梳理,最好是能明白业务场景。 就举个例子: 财务系统,这是目前大公司都会具备的吧,那换个角度去思考的话,如果我只晓得了财务系统的话,那我是不是在梳理相关场景或者相关指标的情况下,是不是就轻松很多了呢? 然后在整理需求和调研阶段的话,对应的坑以及客户的业务痛点就会很清晰和明白了。
也就是说句直白的话: 对应业务场景和需求痛点,不论是不是站在产品的角度或者开发的角 ...
JVM的JIT优化
😀 这里写文章的前言:JVM(Java虚拟机)中的JIT(即时编译器)是一种优化技术,它将字节码实时编译成本地机器码,以提高Java应用程序的执行性能
📝 逃逸分析逃逸分析并不是直接的优化手段,而是一个代码分析,通过动态分析对象的作用域,为其它优化手段如栈上分配、标量替换和同步消除等提供依据,发生逃逸行为的情况有两种:方法逃逸和线程逃逸
方法逃逸:当一个对象在方法中定义之后,作为参数传递到其它方法中;
线程逃逸:如类变量或实例变量,可能被其它线程访问到;
如果**不存在**逃逸行为,则可以对该对象进行如下优化:
同步消除(只能消除JVM的sync锁)、栈上分配
📔标量替换
标量是指不可分割的量,如java中基本数据类型和reference类型,相对的一个数据可以继续分解,称为聚合量;
如果把一个对象拆散,将其成员变量恢复到基本类型来访问就叫做标量替换;
如果逃逸分析发现一个对象不会被外部访问,并且该对象可以被拆散,那么经过优化之后,并不直接生成该对象,而是在栈上创建若干个成员变量;
通过-XX:+EliminateAllocations可以开启标量替换,
-XX ...
大数据组件知识_记录
😀 这里写文章的前言:大数据组件需学知识记录
📝 Zookeeper
选举机制
使用场景
Paxos算法
CAP原则
📝 Kafka
基础架构
副本数
压测
台数
分区数
保存策略
消费者策略
监控
topic数
数据量
积压/borker/数据重复/kafka宕机/可重复/高效读写
📝 Hive
客户端,JDBC,编译器,优化器,执行器
内部表,外部表
order by : 全局排序 sort by : 分区内排序 distribute by : 分区 clsuter by 相当于 distribute by & sort by 相同字段
系统函数
自定义函数
Hive优化
数据倾斜
📝 Spark
部署模式
RDD
计算分区/计算逻辑/血缘依赖/分区器/移动数据
共享变量: 累加器/广播变量/cache&Checkpoint
算子
手动重分区
行动算子
几种划分: 划分job/划分stage/划分t ...
JVM垃圾回收
😀 这里写文章的前言:JVM的垃圾回收机制
📝 简介Java 的对象使用的是堆空间的内存, 方法的执行是栈帧的入栈出栈, 引用和局部变量可以随着入栈出栈直接清理, 但是引用对应所在堆空间的内存则不能通过出栈的结束而回收, 因为堆空间是线程共享的, 并不确定是否有其他线程引用了这块内存, 需要 GC 机制来进行自动的清理
**📔**垃圾收集
程序计数器,虚拟机栈和本地方法栈 这三个区域属于线程私有,只存在于线程私有的,只存在于线程的生命周期内,线程结束后,因此不需要三个区域进行垃圾回收
垃圾回收主要针对JVM的 堆空间 和 方法区进行
判断一个对象是否可回收
引用计数: 给对象添加一个引用计数器,当对象增加一个引用计数器加1,引用失效时计数器减1。引用计数为0时,可被回收
缺点: 两个对象出现循环引用的情况下,此时引用计数器永远不为 0,导致无法对它们进行回收
objA.instance = objB;objB.instance = objA;
可达性分析
通过** GC Roots** 作为起始点进行搜索,能够到达到的对象都是都是可用的,不可达的对象可被回收
GC ...
Java对象创建过程
😀 这里写文章的前言: Java创建一个对象的流程
📝 创建对象流程
检查加载类加载器会维护一个加载的类的集合,通过检查该集合中是否已经存在类的定义,来确定是否需要重新加载类的字节码。
如果类还没有被加载过,类加载器会尝试从指定的位置加载类的字节码,并进行必要的解析和链接操作。如果类已经被加载过,类加载器会直接返回该类的引用,无需再次加载。
分配内存当类被加载完之后,虚拟机就会给对象分配内存,此时对象的大小已经确定,虚拟机会从的内存域中划分出该对象大小空间的区域供存放该对象
指针碰撞把堆上的一部分内存分成两部分,一部分依次放满了对象,此时对象在这部分内存上是整齐排放着,另一部分是空白内存区域,等待放对象。两块区域的间隔点是用一个指针进行标记,如果在这块内存中又创建了对象,则指针会向后移动这个对象的大小的地址,供这个对象存放
指针碰撞的优点是分配速度快,只需要移动指针即可完成分配,无需进行复杂的内存搜索或碎片整理。然而,这种方式只适用于具有连续内存布局的情况,例如使用标记整理或复制算法的垃圾回收器。
空闲列表当内存上存放的对象不是整齐规整存放的话,此时内存空间就会碎片化,就不 ...







