PCC 是 Performance Challenge Championship (性能挑战杯)的缩写,是高可用架构后花园会员在线上组织的一个活动,由于反响热烈,考虑到线下进行可以更好的加深对高并发编程的理解,于是高可用架构在 3 月组织了本次 PCC 活动。

对于工程师来说,参加 PCC 编程挑战赛的部分意义:

  • 体验完成一个技术小目标。高性能系统如何实现应当是每个工程师需要走的路。

  • 学习优秀的架构方法,隔壁老王用的设计思想,可能你坐在办公室永远也无法想到。

  • 有经验评委的点评,了解真实环境的高并发系统的追求目标。

类似主题、有同样级别参赛队员及评委参加的编程活动,可能仅此一次。

比赛方法说明

实现类似 facebook 中的 like 功能,需要:

  • 可以对一个对象(一条feed、文章、或者url)进行 like 操作,禁止 like 两次,第二次 like 返回错误码

  • 有 isLike 接口,返回参数指定的对象有没有被当前用户 like 过

  • 需要看到一个对象的 like 计数

  • 可以看到一个对象的 like 用户列表(类似 QQ 空间);

  • 上述列表加分项:Like优先显示我的好友列表(social list)。

数据量:每天新增的 like 对象数为 1 千万,每秒 like 计数器查询量为 30 万次 / 秒。

比赛盛况

比赛题目在比赛前就发给了选手,实际上不少选手头一天晚上已经可以将功能跑通,第二天的时间主要用于优化。

第二天早上,选手陆续来到比赛现场,和一般的活动热闹现场的区别是,PCC 比赛的现场异常的安静,因为选手都在潜心优化及调试代码,1天的时间实际是非常短的,必须抓紧每一分一秒。中午吃饭的时间大家也都匆匆交流了十几分钟,又回到电脑前继续开发。

大赛组委提供的模拟数据

https://github.com/archnotes/PCC/tree/master/data

到傍晚,经过1天的角逐,代码都写得差不多了,就等压测了……

PCC 评委领宇鹏(一乐)

组织方突然放出 200G 的测试数据,虽然是内网,但是几十人在云平台内部传输这么大数据也是一场风暴,考虑到已经没有选手使用纯内存方案,组织方简化了一下条件,测试数据被压缩到 40G,数据需要选手自行导入自己的系统中,不过导入速度依然慢得超出了大家自己的期望。各种新的问题开始冒出来了,真正体现高性能优化效果的时刻。

尽管大家还沉浸在优化的过程中不能自拔,到了晚上 8 点,评委宣布截止比赛,并根据比赛的规则宣布了入围名单。

优秀作品展示

图:入围奖选手及评委

参考实现:方圆

项目地址:https://github.com/archnotes/PCC

入围奖作品介绍

入围奖:覃冠日

我采用的是 OpenResty + Pika 的架构,OpenResty 能支持高并发的请求处理,使用 Lua 脚本完成业务逻辑处理,利用 OpenResty 的 sharedict 完成数据的缓存。存储层使用 Pika,利用有序集合、hash 等数据结构存储用户数据。

项目地址:https://github.com/qinguanri/demo_lua

入围奖:夏海峰

从架构的简单,可扩展,低耦合的角度考虑,我选择了微服务架构;同时从一个完整的业务系统的角度考虑,将整个系统分为了 article, user, action 三个微服务系统。三个微服务主要功能有:

  • article - 处理 article 的存储,查询等功能

  • user - 用户账户信息的存储,用户登录等功能

  • action - 存储用户的操作行为,包括点赞,添加好友等功能 (各种行为其实还可以再细分为不同的微服务)

微服务之间使用 gRPC 来获取信息;对于数据的写入,通过 NSQ 来传递到不同的微服务系统,实现数据的异步写入,达到数据的最终一致性。

数据存储上,采用了 SQL + NoSQL 缓存的模式。由于数据量的限制,使用内存缓存是不太可能的;所以这里选择了 SSDB(Leveldb + Redis 协议)作为数据缓存。为了减少不必要的存储空间的占用,使用了 Protobuf 作为数据交换格式。缓存主要有两类东西:实体 + 列表。列表主要解决了 “点赞” 用户列表的查看,翻页问题。

我的项目中,对 优先显示点赞用户中我的好友 这个需求理解错误;这个需求,将我的好友和点赞用户做个交集是一个比较简单清晰的方案,这在微服务架构中很好扩展。

主要的技术栈:Golang, Postgresql, SSDB,NSQ,Protobuf, gRPC,Microservices,RESTFul API

项目地址:https://github.com/chideat/pcc

入围奖:陈刚

缓存设计

  • feedLike 计数器:key:like_count:feed_id;value: 存储 String,like, unlike 操作时,分别 incr,decr。

  • likeList 列表:key: like_list:feed_id;value:lists,like 时,rpush 插入用户 id,unlike 时,srem 删除对应的用户 id。

  • friends 列表:key: friends:uid;value:lists,存储所有好友的 uid 列表。

  • 点赞的好友列表:key:like_friends:feed_id;value:lists,likeList 列表与 friends 列表求交集,得到好友 list。

  • 点赞的其他人列表:key:like_others:feed_id;value:lists,likeList 列表与friends 列表求差集,得到非好友 list。

注: 由于数据量大,所以要采用 redis cluster 来存储。同时,由于要求交集,是否要求两个 list 必须在同一 shard 上,这个在 redis cluster 尚未验证。

性能优化

依据场景可以做一些裁剪,真实情况下,赞列表很少翻到后面,可以在缓存中只存储前 100 条数据,减少存储量。当翻页到 100 条后,再通过数据库,获取后面的数据。

如果好友关系变化不影响历史的话,每个 feed 可以设计两个赞列表,一个好友的,一个非好友的。在数据写入时,就计算好,分别写入,提升读性能。 (如果好友关系实时变化,需要重新计算数据)

实现

关系数据库:MySQL 5.7

计数、查询缓存:Redis

接口实现:spring-boot

项目地址:https://github.com/iqinghe/pcc-like

二等奖

最后,经过评委对架构打分集体商议评比后,产生了 PCC 的二等奖。

图:二等奖选手及评委

二等奖 黄东旭

项目地址:https://github.com/c4pt0r/pcc

二等奖 唐福林

作为一个 local cache 的坚定拥护者,在第一眼看到这次比赛题目的时候,就已经决定了要用 local cache 来做。

唯一的问题是,Java 技术圈里,local cache 不少,但真正适合大量数据的却不多。 曾经在线上环境用过 ehcache,也用过 hazelcast ,非线上环境尝试过 mapdb 。这一次,想试试号称为“高频交易”而生的 Chronicle-Map 。

选中 Chronicle-Map 是因为:

  • Map 接口,使用简单

  • off heap,无 gc 压力

  • mmap 文件,支持重启不丢失数据

为了解决 value 长度差别过大,导致写入文件性能低下的问题,我在原生的 Chronicle-Map 外面包了一层 ListmapService,用多个不同的 map 来存储不同 value 长度的数据。于是这个方案的重点就变成了如何根据数据的分布选择合适的 map size 的问题了。

用 Springboot 写微服务如行云流水,半天时间连 test case 都写好了。但写到 cursor 翻页的地方,我才反应过来,简单粗暴的的数组并不是一个很适合存储 like 列表的数据结构。果然,在后面的导入数据环节,因为数据结构不够高效,导致导入速度非常缓慢,简单的做了一下并发导入的优化,但效果依然不够理想。

比赛结束后,回过头来想想,这样的比赛对于码农来说确实非常有帮助,既锻炼了写码速度,又开拓了架构眼界。唯一不足的是,很多参赛方案最后都演变成了开源组件选择比赛,选 nginx,选 redis,选 leveldb,选来选去,最终也没有选出一个因为所以来。

项目地址:https://github.com/tangfl/chestnut

压测程序说明

本次性能挑战赛使用的压测程序是 Tsung。Tsung 是一个开源的性能测试工具,能用来压测 HTTP, WebDAV, SOAP, PostgreSQL, MySQL, LDAP 和 Jabber/XMPP 等服务。它支持分布式压测,将压力分布在多个测试机,模拟数十万甚至更多的虚拟用户数并发产生压力。

感谢 @left2right 贡献压测程序

一等奖

那有看官要问了,PCC 一等奖花落谁家呢?由于本次参赛时间比较短,测试数据集也比较大,无法在有限时间内完全决出跑分胜负,我们期待上面的选手能够继续优化工程,能够在代码优雅方面具有广泛的借鉴参考价值,并且跑分持续领先的话,PCC 一等奖的大门是一直打开的。

感谢


本次挑战赛活动的高性能云服务平台由青云提供支持。


感谢青云的场地以及在许多在背后默默支持活动的小伙伴们。 感谢大赛评委梁宇鹏、刘奇、王渊命的热心支持。

想进一步了解 PCC 代码,请访问 PCC 项目仓库

https://github.com/archnotes/PCC

推荐阅读

  • 首届高可用架构PCC性能挑战赛于3月在北京举行

  • 获得PCC性能大赛背后的RocksDB引擎:5分钟全面了解其原理

高可用架构

改变互联网的构建方式


长按二维码 关注「高可用架构」公众号

如何快速获得高并发编程经验?PCC性能挑战赛作品简介及源代码相关推荐

  1. 啃完阿里这份高并发编程核心笔记,反手涨了 5K

    高并发编程 提到并发编程很多人就会头疼了:首先就是一些基础概念:并发,并行,同步,异步,临界区,阻塞,非阻塞还有各种锁全都砸你脸上,随之而来的就是要保证程序运行时关键数据在多线程中的可见性.核心业务的 ...

  2. 啃完阿里这份高并发编程核心笔记,反手涨了5K

    高并发编程 提到并发编程很多人就会头疼了:首先就是一些基础概念:并发,并行,同步,异步,临界区,阻塞,非阻塞还有各种锁全都砸你脸上,随之而来的就是要保证程序运行时关键数据在多线程中的可见性.核心业务的 ...

  3. 【高并发编程】之高并发理论

    一.前言 高并发,几乎是每个程序员都想拥有的经验.原因很简单:随着流量变大,会遇到各种各样的技术问题,比如接口响应超时.CPU load 升高.GC频繁.死锁.大数据量存储等等,这些问题能推动我们在技 ...

  4. 高并发编程系列:NIO、BIO、AIO的区别,及NIO的应用和框架选型

    谈到并发编程就不得不提到NIO,以及相关的Java NIO框架Netty等,并且在很多面试中也经常提到NIO和AIO.同步和异步.阻塞和非阻塞等的区别.我先简短介绍下几个NIO相关的概念,然后再谈NI ...

  5. Java高并发编程详解系列-Java线程入门

    根据自己学的知识加上从各个网站上收集的资料分享一下关于java高并发编程的知识点.对于代码示例会以Maven工程的形式分享到个人的GitHub上面.   首先介绍一下这个系列的东西是什么,这个系列自己 ...

  6. Java高并发编程学习(三)java.util.concurrent包

    简介 我们已经学习了形成Java并发程序设计基础的底层构建块,但对于实际编程来说,应该尽可能远离底层结构.使用由并发处理的专业人士实现的较高层次的结构要方便得多.要安全得多.例如,对于许多线程问题,可 ...

  7. 《深入理解高并发编程:JDK核心技术》-冰河新书上市

    大家好,我是冰河~~ 废话说多了没用,并发编程技术一直是初级程序员进阶高级工程师的前提条件,也是成为大厂程序员的必备技能,更是突破自身技术瓶颈的必经之路. 2022年6月我出版了"冰河技术丛 ...

  8. 几乎涵盖高并发所有知识点,Alibaba版开源内网高并发编程手册.pdf|高清下载

    而今天分享的这份阿里内网"M9级全彩高并发编程手册",让大家不仅能够学到深度.专业的编程知识,还能感受到阿里专注地提高编程技能的态度,始终如一地贡献.分享Java专业知识与经验的精 ...

  9. 纯干货 | 大佬总结的 20 个高并发编程知识点!

    点击蓝色"架构文摘"关注我哟 加个"星标",每天上午 09:25,干货推送! 转载自并发编程网 – ifeve.com 一.前言 借用Java并发编程实践中的话 ...

最新文章

  1. GOF23设计模式(创建型模式) 原型模式
  2. python arcade库是干什么的-Python街机模块arcade的鼠标移动与单击示例
  3. 日历记事本java代码_急需日历记事本JAVA源代码
  4. 软件工程个人作业03—找水王
  5. 表单内如何直接贴图而不用上传图片_重磅更新|偷偷告诉你,表单大师官网改版啦啦啦啦...
  6. c语言jam的随机数,c – 如何重置随机数引擎?
  7. UI设计师必收藏的上百种配色方案专辑!
  8. Linux内核分析作业 NO.2
  9. 浏览器tab切换最小化,当前页面无操作刷新页面
  10. 7x android 8,内测开启 华为荣耀畅玩7X升级Android 8.0
  11. AI笔刷 600+专业ai矢量笔刷套装(含安装教程)
  12. python打印数组
  13. 格兰杰因果 Granger causality
  14. bzoj3168 [Heoi2013]钙铁锌硒维生素(矩阵求逆+匈牙利)
  15. 什么软件可以给图片去雾?分享三种图片去雾软件给你。
  16. 机器学习中的评估指标与损失函数
  17. 离职前一定要删除这几个文件,不然你的微信聊天记录全被别人看了
  18. oracle错误代码大全(超详细)
  19. 关于maven更新超时问题显示报错
  20. 程序猿来做一下这套试卷,看看你的实力如何!

热门文章

  1. java终结者怎么样_终结者6:丹妮与约翰康纳相比怎么样?她绝对也是个好领袖!...
  2. 百度地图AndroidSDK:定位、画区域、线路规划、搜索
  3. php轮播效果代码,CSS实现轮播图效果(附代码)
  4. XShell的会话文件存放目录
  5. python中稀疏矩阵的常用表示COO LIL CSR CSC【上篇】
  6. nmake工具的用法
  7. 年年都有人说Java市场饱和,那Java行业到底是不是真的饱和了呢?
  8. 171122之PLSQL的使用教程
  9. 用threejs创建流动的水管
  10. 如何使用Python制作人脸识别系统(2022/5/28版)持续更新