`

Json压缩方案 极限逼近——JSON四步香艳瘦身的故事

 
阅读更多

极限逼近1——JSON四步香艳瘦身的故事

CUC 黄进兵

概要:

中国联通总部有一个自助服务的项目,其中一个功能是要为联通用户在线上提供详单查询服务。由于详单存在多次重复查询的情况,如果每次都要通过接口去调用省分BSS系统的话,极度影响用户体验,特别是在用户能随意调整选择查询时间范围的时候,频繁调用接口也会让对端系统受不了。因此当时一个容易想到的方案,就是直接在用户查询详单时,把该用户最近一个月乃至三个月的详单,一把头地从BSS中拿过来,放在自助服务本身的HBASE数据库中缓存起来,然后通过这个系统内的缓存,为用户提供良好的详单查询体验。

在具体项目实现中,当时采用一种“偷懒”的方案,就是直接把详单JSON作为一个整体,存储到HBASE中,然后使用的时候,又一把头读出来,有点像银行的“整存整取”,实现起来相当方便。上线后产生的问题是,这种存储方案会导致每天详单的增量都在1T左右,对存储增长要求非常高。因此,当我了解到这个问题后,就给项目组提供了一个简单的优化方案,能在不改变“整存整取”方案的前提下,把详单存储容量降到原来的20%左右。本文就是向大家分享一下这一JSON瘦身的研究过程。

一、四步瘦身计划

首先就是样本分析,找我的同事蔡淑华要来了几段详单的样本,我要仔细端详一下,看看他们长的是什么样子。下图中,我截取了其中有代表性的一段,共1532个字节,如果把字节比喻成重量的斤的话,那么这段详单JSON就有1532斤,如果要“性感”比喻一下,那就是:对面的“女孩”看过来,原来是肥妞一枚。由于太肥了,感觉还是躺着舒服,坐着都费力,站起来就别想了。

怎么办,请将目光从右边的“肥妞”转移到左边的JSON数据上。眼睛不要离得太近,离远点,会发现这个JSON中,怎么满满的都是双引号啊。JSON中的KEY左边右边2个双引号,VALUE左右又两个双引号。当然标准JSON中,KEY是需要两个双引号包含起来的,VALUE如果是字符串类型的话,也是需要用两个双引号包含起来的。一个KEY-VALUE就需要4个双引号。如果先把JSON标准放一边,在VALUE全部都是常规字符串类型的情况下,把双引号消除(裸奔处理)的话,会不会影响JSON的语义呢?先下手为强,消除掉试试看。由于消除了所有的双引号之后,并没有破坏JSON的结构,因此并没有破坏JSON的语义,这么做就是无害的。此时,我们再上称称一下,发现比原始体重减掉了334斤。虽然第一步就减到了1198斤,但是还是胖啊,不过好歹站起来不费力了。

让我们再次在上图中将目光从右边移到左边,稍微拉近点距离,仔细端详一下,是不是还有比较明显的“肥肉”呢。很容易就发现,每一条详单的KEY名字都好长。Calldate通话日期、calllonghour通话小时、calltime通话时间、othernum对方号码……我们再看看VALUE,发现到处都是0.00,到处都是20130101,到处都是“国内通话”。根据处理重复的“三次原则”,如果重复达到3次,那么就可以将重复提炼出来,消除重复。这一步,我们依然不破坏JSON的结构,但是把KEY提炼出来,做一个映射,将长的名字映射成短的名字,把VALUE重复达到三次的,也提炼出来,给一个短名字的引用。经过这第2步的瘦身,多了两个字典的JSON,再加上瘦身过后的JSON,总共是846斤,欧耶,又成功甩掉352斤的肥肉,减到了846斤,如下图,这次不仅可以站起来,还可以运动起来了,这个美女大家都想要了吧。

经过上面的2步减肥,效果已经很不错了。目光自觉地再次移到左边的JSON上,名字都很短了,重复的VALUE也用@开头的名字来引用了。唯一的一点遗憾就是,每一条话单,都有一套一模一样的KEY。我们将KEY做成表头,将VALUE做成纯的数据行,将JSON对象转换成JSON数组,就又可以成功减掉118斤了。

经过3步减肥,效果已经很明显了,从原来的1532斤减到了728斤,减掉了将近一半。再从字面上去减的话,基本上到顶了。那么能不能通过压缩来进行压缩呢,很快实验一下GZIP压缩并且以BASE64编码来表示,发现又成功减肥了173斤。这次减肥,相当于把美女蜷缩起来装进了箱子。

样本成功瘦身了。我们再拿一个真实的大小184K的详单来进行实验,经过4步瘦身后,可以减到6K,效果杠杠的。

所有的这些“瘦身”都是无损的,也就是完全可以以相反的顺序来恢复成原始模样。我把前面的3JSON实验的代码,也已经分享到了GITHUB上( https://github.com/bingoohuang/westjson )。加入你看不惯打印到日志中那么多JSON中的双引号的话,就可以引用westjson,通过调用new WestJson().json(standardJSON, WestJson.UNQUOTED)就很方便地把双引号消除掉,再通过调用new WestJson().parse(unquotedJSON, WestJson.UNQUOTED)就可以恢复到标准JSON

二、总结思考

首先,我们应当不拘泥于标准的JSON格式,这样我们才能放手去做一些事情。标准只是参考而已,对外接口的时候需要保持,内部使用的时候可以适当调整。本文还是以文本格式为基准的瘦身过程,其实除了文本格式的JSON之外,也有二进制的BJSON(谷歌搜索Binary JSON即可),如果采用BJSON是否可以达到更高的瘦身效果,需要进一步去研究。

其次,消除重复的“赘肉”永远效果是最佳的。把相同的反复重复的数据进行规整,只存储一份原始数据,这样重复越多,瘦身效率越高。

最后,是GZIP压缩,应当也可以通过HBASE相关的压缩选项来完成,这样应用本身就可以忽略压缩这一步了。

       有人会有疑问,这点瘦身放在若干条详单上到底有没有必要。还是引用一位90岁老太太谈南海局势的话吧:“南海是中国的,要不观音菩萨住哪里,东海也是,要不龙王住哪,月球也是,要不嫦娥住哪。有什么好协商的,打仗就是打钱,国家14亿人口,每个人10块就是140亿,先打10块钱的,不够再打100块钱的,打他。“你若干条话单费那么大力省那么点存储,意义没那么明显,但是如果是上千万上亿的话单,省下来的那可不得了。

分享到:
评论

相关推荐

    python实现json diff(csdn)————程序.pdf

    Python 实现 JSON Diff Python 是一种流行的编程语言,它提供了许多强大的库和工具来处理 JSON 数据。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它广泛应用于 web 开发、移动应用开发、数据...

    如何解决@RequestParam无法接收vue+axios传递json数据(csdn)————程序.pdf

    4. 解决方案 为了解决这个问题,我们需要修改Controller的方法,使用@RequestBody注解来接收JSON数据: ```java @RequestMapping(value = "/getToken", method = RequestMethod.POST, consumes = "application/json;...

    按字母A——Z排列的中国城市(地级市)json数据

    按字母A——Z排列的中国城市(地级市)json数据 按字母A——Z排列的中国城市(地级市)json数据 按字母A——Z排列的中国城市(地级市)json数据 按字母A——Z排列的中国城市(地级市)json数据

    python 处理json数据(csdn)————程序.pdf

    Python处理JSON数据是编程中常见的任务,特别是在Web开发和数据交换场景下。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它易于人阅读和编写,同时也易于机器解析和生成。在Python中,我们可以...

    Go-基于json的数据压缩工具

    这个Go工具——DataCompress,通过实现json数据的压缩,旨在减少存储空间的占用,提高数据传输效率。它可能采用了常见的压缩算法,如DEFLATE(用于gzip和zip)、LZ4或LZMA等。这些算法通过查找和替换重复的字节模式...

    7、使用JSON向服务器发送数据——ajax基础笔记

    在“使用JSON向服务器发送数据——ajax基础笔记”这个主题中,我们首先会了解如何创建一个XMLHttpRequest对象。在JavaScript中,你可以通过`new XMLHttpRequest()`来实例化一个对象,然后利用它的方法如`open()`、`...

    JSON Schema 校验库——json-schema-validator(java版本).rar

    在给定的压缩包中,`JSON Schema 校验库——json-schema-validator(java版本).pdf`可能是该库的使用指南或API文档,可以帮助开发者深入理解如何在Java项目中有效利用`json-schema-validator`进行JSON数据验证。...

    json系列文章——json的使用

    这篇“json系列文章——json的使用”将深入探讨JSON的基本概念、语法以及在实际开发中的应用。 1. JSON的基本结构 JSON由键值对组成,以大括号 `{}` 包裹。键用双引号 `"key"` 指定,值可以是字符串、数字、布尔值...

    Json-jar(0——)

    Fastjson是一个Java语言编写的高性能功能完善的JSON库。它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSON库。Fastjson接口简单易用,已经被广泛使用在缓存序列化、...

    mybatis中操作json类型数据(csdn)————程序.pdf

    在MyBatis中,操作JSON类型数据涉及到对MySQL数据库中JSON字段类型的映射和转换,以便于在Java代码中能够方便地处理这些数据。这里,我们主要关注如何自定义TypeHandler来实现这一功能。 首先,MySQL引入了JSON类型...

    JSON — JSON入门与实战详解 —— JavaScript、Java与JSON互转

    NULL 博文链接:https://jiangzhengjun.iteye.com/blog/463038

    JSON Schema 生成库——json-schema-inferrer(java版).rar

    JSON Schema 是一种JSON格式的规范,用于定义JSON数据的结构和限制,类似于XML Schema和DTD(文档类型定义)。它在API开发、数据验证、数据交换等场景中扮演着重要角色,确保了数据的一致性和准确性。`json-schema-...

    json压缩,去掉空格、换行

    在日常的web前端开发过程中,将骨骼动画中、或者其他大的json文件去掉空格、换行,压缩,是每次发布过程中必须的操作

    JSONC, JSON压缩器和解压缩器.zip

    JSONC, JSON压缩器和解压缩器 JSONC 版本更新到版本 变更日志文件背景使用Javascript开发富internet应用程序( RIA )的一个问题是传输到服务器和从服务器传输的数据量。 当数据来自服务器时,这个数据可能被压缩,...

    json-lib含使用说明

    在Java开发中,json-lib是一个非常实用的库,它提供了处理JSON对象的方法,包括序列化Java对象到JSON字符串以及将JSON字符串反序列化为Java对象。本篇文章将详细介绍json-lib的使用方法。 首先,json-lib提供了两个...

    activiti 汉化 stencilset.json 文件内容(csdn)————程序.pdf

    在 activiti 流程引擎中,stencilset.json 文件是一个至关重要的组成部分,它定义了流程图中的图形元素以及它们的属性。这份文件的汉化工作是针对中国开发者优化的,使其能够更方便地理解和使用 Activiti 的流程编辑...

    ASP 使用jqGrid实现读写删的代码(json)

    response.Charset=”utf-8″ ‘————————————— ‘ JSONClass类 ‘ 将Select语句的执行结果转换成JSON ‘—————————————— Class JSONClass ‘ 定义类属性,默认为Private Dim SqlString ...

    用stanfordCoreNLP进行中文分词时出现json编码错误(csdn)————程序.pdf

    5. **查阅文档和社区资源**:如果问题依然存在,可以查阅stanfordCoreNLP的官方文档或相关社区(如CSDN、Stack Overflow等)寻找解决方案。其他开发者可能已经遇到并解决了类似的问题。 总的来说,处理这类错误需要...

Global site tag (gtag.js) - Google Analytics