Redis系列之初出茅庐

首先,给大家讲一个关于小明的故事。

小明的一天

小明是一名应届生,从大一接触C语言后就励志要做一名凭借自己双手改变世界的程序员。经过4年的努力,他也如愿以偿地拿到了某个特别火热的UGC平台的研发offer。在经过短暂的实习后,他正式步入工作岗位。

小明哭了

有一天晚上,在小明正准备回家的时候,产品MM来找他说要做一个排行榜功能:“要在一个页面中展示发表评论最多的Top10用户”,还说是老板提的,明天就要上线。小明一听不敢怠慢,心想是时候展现自己的才华了,便立刻在工位上陷入了沉思。

评论表的定义是这样的:

CREATE TABLE `news_comment` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `author_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '作者Id',
  `news_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '新闻Id',
  `content` text NOT NULL COMMENT '评论内容',
  `created` datetime NOT NULL,
  `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `up_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '赞数',
  PRIMARY KEY (`id`),
  KEY `idx_news_id` (`news_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='评论表'

第一个想法很快诞生,不就是要Top10吗,直接从db把结果查出来不就行了嘛。 group by order by一句sql搞定。同时作为一个在学校就做了很多项目的他,一下就想到了可以通过在author_id上加个索引以提升查询效率。

首先,建索引:

alter table news_comment add index `idx_author_id` (`author_id`);

接着,写出查询sql:

select author_id, count(*) as comment_count from news_comment group by author_id order by comment_count desc limit 10;

又然后,经过了短暂时间的啪啪啪啪,全部搞定!接下来怎么办?肯定是上线啊。 不行,还是要先在线下测一下�吧,怎么测呢?

首先,他很聪明的想到要先借助一个简单的存储过程在线下库mock一批数据

(PS:如果大家看不懂下面的存储过程,可以先忽略,你只要知道我们这一步是往我们的线下库插入了1000W数据即可。)

create procedure add_data(num int)
begin
  declare i int;
  declare news_id int;
  declare author_id int;
  set i=0;
  while i<num do
      SET news_id = MOD(i, 10000) + 1;
      SET author_id = MOD(i, 100000) + 1;
      insert into news_comment(author_id, news_id, content, created) values(author_id, news_id, '评论内容', NOW());
      set i=i+1;
  end while;
end

然后,调用这个存储过程来为mock数据

call add_data(10000000)

伴随着一万匹草泥马路过,数据终于造好了(PS:过程比较慢,大家可以在自己的机器上跑一下)。

最后,到了最关键的一步了,调下接口看看成果吧~ 要下班啦要下班啦

只听回车键啪的一声,1s过去了... 2s过去了... 等了N秒之后结果才展示出来。此时此刻,小明的内心是崩溃的。

一定是网络原因,紧接着又是一声回车键,然后~

网络看不下去了,大喊道:“这锅我不背!”。小明不得不承认,这不是网络原因。

怎么办?赶紧查原因吧,先从最底层查起,看看查询sql用了多长时间。小明得到了下面的结果

mysql> select author_id, count(*) as comment_count from news_comment group by author_id order by comment_count limit 10;
+-----------+---------------+
| author_id | comment_count |
+-----------+---------------+
|     59206 |           100 |
|     63302 |           100 |
|     40004 |           100 |
|     44100 |           100 |
|     63975 |           100 |
|     68071 |           100 |
|     72072 |           100 |
|     76168 |           100 |
|     88106 |           100 |
|     92202 |           100 |
+-----------+---------------+
10 rows in set (2.09 sec)

水落石出!怪不得请求这么慢,光花在db的查询时间就这么久,得赶紧想办法解决了。
这时,小明落下了委屈的泪水:”我想回家~~~“
(PS:想知道为什么这么慢?请关注我后面的文章哦,如果你已经知道了可以忽略)

小明笑了

哭是没用的,小明告诉自己要振作起来。马上又陷入了新一轮思考。

很快,小明又想到了第二种方案。

  1. 通过定时Task,每5s从db中查询出top10结果,放到固定的存储空间中。
  2. 用户请求top10结果时,可以直接从该存储空间中读取返回给用户。

但该方案有两个要解决的问题。

  1. 由于top10结果是定时Task每5s计算一次,也就意味在第N个任务执行后,第N+1个任务执行前的这段时间内,读取的结果都是基于“第N次计算时的数据集合”计算出来的。所以存在一定的误差。
  2. 由于我们的核心诉求就是降低响应时间,所以存储空间的读取性能一定要非常高。

首先第一个问题,在跟PM说明问题后,PM很爽快的就答应了。那么第二个问题,就要靠自己来解决了。

突然,小明灵光一现,想到了一个存储空间,那就是Redis!

前方高能!前方高能!
(PS:一篇讲Redis的文章,到现在才提到,也是没谁了,大家再忍耐一下继续看完)

  1. Redis是一个由C语言编写的开源的key-value数据库。
  2. Redis将所有的数据都保存到内存中。
  3. Redis性能极高,由于将数据保存在内存中,再加上内部独特的设计和实现,读QPS能达到11W,写QPS能到达8W。

当然,这些只是Redis的其中一部分特性,但已经完全可以满足我们的需求。

解决了存储问题,一条完整的解决方案出现在小明的脑海里。

  1. 异步任务计算Top10,计算结果放到Redis,key = authorIds,value = #{计算出来的结果},并且该任务5秒钟重新计算一次并更新value。
  2. 用户请求Top10展示,直接从Redis中读取key = authorIds 的值,返回给用户即可。

接下来,又伴随着一大波啪啪啪啪的键盘声,小明终于搞定了这个需求。

小明抬头一看,此时正好4点钟。他想起了自己偶像说过的一句话:“你见过凌晨4点钟的洛杉矶吗?”

“是的,那时候我刚下班”,小明情不自禁的说。

(PS:我真的是科密)

Ending

整个故事结束了。从这个故事中我们可以看到,当数据量达到一定的量级的时候,传统的关系型数据库就会暴露出一些问题,而这些问题必须通过其他的方式去解决,比如我们提到的Redis。

其实这篇文章关于Redis的知识很少,但我想任何一个刚接触Redis的人都不想一开始就学习他的语法,而是想知道Redis到底有什么用?有哪些场景可以用到?他能给我们带来什么?从上面小明的例子中,我想大家或多或少能对Redis有了一个初步的认识,如果你因此对Redis产生了兴趣,那就好好学下去吧~

接下来,我会根据这个故事中提到的关于Redis点,来跟大家进行深一步的探讨。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351

推荐阅读更多精彩内容