大家好,我是贺同学。

前段时间在工作业务中碰到一个技术问题, 在发现问题,思考问题,解决问题的过程中,突然对底层原理有了一些思考,这里分享一下给大家。

背景

在业务中使用到了 Redis 数据库来存储数据,但是在存储大数据量的 string 的时候,监控却发现内存增长异常。

string 类型,作为 Redis 中唯一的“键-单值”类型,操作简单,易于理解,按道理只是存一下字符型的数据,怎么会这么消耗内存,这是怎么回事呢?

怀着刨根问底的精神,我自己在我的 Mac 机器上动手实战了一番,写了一段 Python 代码,准备数据长度 7 位数,共 100 万条数据,开始跑数据。

结果发现,使用 string 占用 70 MB,使用 hash ziplist 只占用 9 MB!效果非常明显。

测试结果:

begin write 100w
before: used_memory_human:1.87M
before: used_memory_human:70.90M
end write 100w, using: 72380608

这数据效果,没有对比就没有差距。

百思不得其解之际,上网搜了搜别人的回答,看了一些但感觉一直没有说到点子上,直到今天在极客时间的专栏上,学习了 Redis 的 string 底层源码。

Redis 的 string 类型和 hash ziplist 的底层数据结构不同导致了存储大小的差异,我才发现,原来是这么回事!

这下我直呼好家伙。

string 类型,常常被当作 Redis 中的万金油,但是它有一个明显的短板,就是它保存数据时所消耗的内存空间最多。

对于不了解 Redis 底层原理的人,很容易误以为最简单的类型,理应消耗最少的资源。但实际情况不是这样的。

Redis string 底层结构,使用了额外的数据结构来保存数据,从而造成了额外的开销,类似这样:

这让我想起了之前的一个业务问题,一个老服务修改了一个功能上线了之后,测试同学反映,压测耗时直线飙升。

大家都觉得很奇怪,这个老服务的耗时一直都很稳定,而且,这次修改也只是正常的业务逻辑,大家又百思不得其解,花了一天的时间排查摸底。

最后我们发现,罪魁祸首居然是线上日志数据太满了,导致机器内存瞬间上升,直接影响到了压测耗时的统计。

后来,我发现,当时这个服务编译的有个选项,开启 log=debug 模式,如果当时能提前了解这个的背后原理,估计就可能避免这个坑了。

内心的疑问

互联网行业,更新迭代非常快,今天学了这个,明天可能又要学那个,在不断持续学习的过程中,相信你心里有时会反问自己,底层原理有那么重要吗?会用不就行了吗?

这个时候,可能会有另一个声音在你耳边响起,万丈高楼平地起,计算机基础知识就像程序员金字塔的地基,理解了计算机系统的底层原理,在写程序的道路上才能越走越远啊。

话是这么说没错,但这真的够吗?

更深处的原因在于:

  • 经常用一些不知其所以然的技术,我会感到不安;

  • 在这个数据爆炸的年代,很多系统对于项目性能的优化有很高的要求。那么如何调优成为了程序员不可避免的问题;

  • 再就是如果你对计算机系统的底层原理不太了解,可能你平时写的程序都是错误的。

比如我们一直以为两个正数的和或者积一定为正,但是用二进制补码表示的正数和或者积却不一定;

程序员和编译器不能用(x-y<0)来代替(x<y),因为前者会产生溢出等等。

更进一步,互联网大厂面试,上来就问底层源码、JVM 的结构、TCP/IP 的三次握手、四次挥手,微信/拼多多用户的数据怎么满足高并发?等等。

像这些问题,如果我们不懂计算机底层知识肯定是不能过关的。

底层原理为何那么重要

开篇的例子引入,其实是想说,底层原理的学习非常重要,就好比数据结构和算法是程序员的内功一样。

最近下班在学习极客时间专栏《MySQL实战 45讲》,作者林晓斌老师分享了这段话,我觉得写得非常棒,在这里分享给大家。

我在带新人的时候,要求大家在写 SQL 语句的时候,心里是有数的,知道每个语句执行的结果,以及这些代码会消耗什么资源、如果慢了会慢在哪里、每个语句执行会占用哪些锁等等。

有的新人会问“为什么需要这么麻烦,我执行一下,看看结果对不对,对了就行,不对就改,是不是也可以?”我说不可以。因为如果这样,我们就会受到很多局限,即使我们定位自己是业务开发人员。

这里我说一个限制:

这会限制基于数据库的业务架构能力。一个语句可以试,一个五个语句的事务分析就要试很多次,一个复杂业务系统的数据库设计,是试不出来的。

原理可以帮我们剪枝,排除掉那些理论上明显错误的方案,这样才有精力真的去试那些有限的、可能正确的方案。

我们不需要 100% 精通 MySQL (我自己离这个目标也相去甚远),但是只要多知道一些原理,就能多剪一些枝,架构设计就能少一些错误选项的干扰,设计出来的项目架构正确的可能性更高。

我自己特别喜欢这个剪枝的过程和感觉,他表示我用以前学习的时间,来节省了现在工作的时间。

当然,“原理”是一个很大的概念,有的原理更接近实战,有的远一些。这个专栏我挑的是跟平时使用相关的原理,以便大家可以有机会边学边用。

一起加油吧

底层原理有那么重要吗?相关推荐

  1. 没有与参数列表匹配的 重载函数 getline 实例_面试题:方法重载的底层原理?...

    前语:微信改版后,大量读者还没养成点赞的习惯,如写得好,望大家阅读后在右下边"好看"处点个赞,以示鼓励!长期坚持原创真的很不容易,多次想放弃,坚持是一种信仰,专注是一种态度. 关于 ...

  2. synchronized底层原理_你用过synchronized吗?它的底层原理是什么?Java经典面试题来了...

    并发编程已经成为程序员必备技能 作为Java程序员,不懂得并发编程显然已经不能满足市场需求了,尤其是在面试过程中将处于被动地位,也有可能面试将就此终结. 那么作为Java开发者的你,日常虽然可以基于J ...

  3. iOS底层原理 - 常驻线程

    iOS底层原理 - 常驻线程 在 AFN 2.0 时代,会经常看到 AFN 创建一个常驻线程的方式: 0️⃣ AFN 2.0 时代的常驻线程 + (NSThread *)networkRequestT ...

  4. elasticsearch原理_ElasticSearch读写底层原理及性能调优

    ES写入/查询底层原理 1. Elasticsearch写入数据流程 客户端随机选择一个ES集群中的节点,发送POST/PUT请求,被选择的节点为协调节点(coordinating node) 协调节 ...

  5. 嘿嘿,我就知道面试官接下来要问我 ConcurrentHashMap 底层原理了,看我怎么秀他...

    来自:烟雨星空 前言 上篇文章介绍了 HashMap 源码后,在博客平台广受好评,让本来己经不打算更新这个系列的我,仿佛被打了一顿鸡血.真的,被读者认可的感觉,就是这么奇妙. 原文:面试官再问你 Ha ...

  6. 面试官再问你 HashMap 底层原理,就把这篇文章甩给他看

    来自:烟雨星空 前言 HashMap 源码和底层原理在现在面试中是必问的.因此,我们非常有必要搞清楚它的底层实现和思想,才能在面试中对答如流,跟面试官大战三百回合.文章较长,介绍了很多原理性的问题,希 ...

  7. 为了把mysql的索引底层原理讲清楚,我把计算机翻了个底朝天

    来自:非科班的科班 什么是索引 概念:索引是提高mysql查询效率的数据结构.总的一句话概括就是索引是一种数据结构. 数据库查询是数据库的最主要功能之一.设计者们都希望查询数据的速度能尽可能的快,因此 ...

  8. 面试官:说说Spring Cloud底层原理?

    点击上方"蓝字", 右上角选择"设为星标" 周一至周五上午11:45!精品文章准时送上! 本文转载自公众号:石杉的架构笔记 目录 一.业务场景介绍 二.Spri ...

  9. Go语言底层原理剖析

    作者:郑建勋 出版社:电子工业出版社 品牌:博文视点 出版时间:2021-08-01 Go语言底层原理剖析

  10. hashmap原理_HashMap和HashTable底层原理以及区别

    HashMap底层原理 哈希表:在哈希表中进行添加,删除,查找等操作,性能十分之高,不考虑哈希冲突的情况下,仅需一次定位即可完成,时间复杂度为O(1). 数据结构的物理存储结构只有两种:顺序存储结构和 ...

最新文章

  1. 太有缘!和同专业师兄同名同姓同年同月同日生还是同导师是什么体验?
  2. python opencv教程rtsp server_Python多进程opencv调用rtsp视频流
  3. 偏方收藏(此信息为本人收藏,安全性无法验证,使用后产生的一些后果自负)...
  4. python软件代码示例-用Python写一个模拟qq聊天小程序的代码实例
  5. 2019最佳年会,新东方6名员工冒着离职的风险,在年会上怒怼老板
  6. 16岁应该遵循什么_成人学习一般遵循的规律
  7. 重新实现unity3d的Mecanim动画混合 (2) 2D Freeform Cartesian
  8. 使用Python解压,对比文件
  9. Maven学习(四)Maven 命令行选项
  10. openstack nova后端使用ceph rbd(增加在线迁移live_migrate和快照snapshot功能)
  11. 遥感软件_遥感软件的可持续发展
  12. C语言知识点笔记完全整理
  13. asterisk sip服务器搭建与配置
  14. 一键推荐螺旋排气集污阀 螺旋除污器 螺旋脱气除污设备厂家供应
  15. Java 集合之SortedSet和SortedMap
  16. Python学习01、计算机基础概念、初识Python、常量,变量,类型和表达式、字符串、动态静态类型、注释
  17. Notification桌面提醒:HTML5新功能
  18. @NotNull,@NotEmpty和@NotBlank使用和区别
  19. n9005zhuenb6 Android 5,三星GalaxyNote3(港版N9005)刷机与ROOT方法-独木成林
  20. Kubernetes引入外部服务与外部数据源

热门文章

  1. C++设计模式学习资料
  2. MogaFX —SWIFT和美国经济
  3. Springboot整合activiti7异常:xxx required a single bean, but 2 were found
  4. android 高仿 探探卡片滑动,Android自定义View仿探探卡片滑动效果
  5. SOLIDWORKS Simulation中如何添加虚拟螺栓
  6. 无线投影+双屏显示 爱普生商务投影全体验
  7. php计数器归零,PHP简单实现文本计数器的方法
  8. 发动机外特性曲线(工况图)疑惑
  9. (只需五步)注册谷歌账号详细步骤,解决“此电话号码无法验证”问题
  10. python中树的介绍