架构

架构

0
评论

【活动推荐】ECUG Con 2018 拥抱下一个十年 ECUG Con 2018 许式伟 ECUG 七牛云

beyond 发表了文章 • 87 次浏览 • 2018-12-03 15:47 • 来自相关话题

国内云计算领域大咖 许式伟
倾情发起的技术盛宴
引领国内云领域风向的高端峰会
ECUG Con 2018
2018 年 12 月 22-23 日 深圳
全新启程!ECUG Con 2018

七牛云 CEO 许式伟

PingCAP CEO 刘奇

七牛云产品副总裁戴文军

Gopher 社区创始人 Asta Xie

阿里巴巴技术专家孙宏亮

《Kubernetes IN ACTION》作者 Marko Lukša

华为云 AI 推理平台&云搜索技术总监胡斐然

七牛云技术总监陈超

阿里云高级开发工程师严明明

京东云区块链实验室与数据库部负责人郭里靖

网易研究院云计算资深架构师朱剑峰

腾讯云高级工程师刘兆瑞

货拉拉数据分析负责人高遥

......
超豪华讲师阵容!

超有料精彩分享!

ECUG 历经十年蜕变

邀您共同开启下个十年

让我们坚持技术情怀,秉承技术精神

开启新的云计算布道篇章!
 
时  间

2018 年 12 月 22-23 日

地  点

深圳市南山区软件产业基地 

更多详情请见下方海报~




扫描上方二维码 ,立即购买早鸟票

与大咖讲师共同探索云计算的下一个十年!
活动详情:了解更多 查看全部
国内云计算领域大咖  许式伟 
倾情发起的技术盛宴
引领国内云领域风向的高端峰会
ECUG Con 2018
2018 年 12 月 22-23 日 深圳
全新启程!
ECUG Con 2018

七牛云 CEO 许式伟

PingCAP CEO 刘奇

七牛云产品副总裁戴文军

Gopher 社区创始人 Asta Xie

阿里巴巴技术专家孙宏亮

《Kubernetes IN ACTION》作者 Marko Lukša

华为云 AI 推理平台&云搜索技术总监胡斐然

七牛云技术总监陈超

阿里云高级开发工程师严明明

京东云区块链实验室与数据库部负责人郭里靖

网易研究院云计算资深架构师朱剑峰

腾讯云高级工程师刘兆瑞

货拉拉数据分析负责人高遥

......
超豪华讲师阵容!

超有料精彩分享!

ECUG 历经十年蜕变

邀您共同开启下个十年

让我们坚持技术情怀,秉承技术精神

开启新的云计算布道篇章!
 
时  间

2018 年 12 月 22-23 日

地  点

深圳市南山区软件产业基地 

更多详情请见下方海报~
30943258454939062.jpg

扫描上方二维码 ,立即购买早鸟票

与大咖讲师共同探索云计算的下一个十年!
活动详情:了解更多
0
评论

【我最喜爱的 Cloud Studio 插件评选大赛】终于开始了! Cloud Studio Cloud Studio 插件评选大赛 腾讯云开发者平台 coding 编程大赛

beyond 发表了文章 • 137 次浏览 • 2018-11-26 15:37 • 来自相关话题

由 环信、腾讯云和 CODING 共同举办的 我最喜爱的 Cloud Studio 插件评选大赛正式开始了!在这场比赛里,将会有技术上的碰撞,大牛评委的专业点评,愉快的技术交流,好玩的插件尝试。





参赛者可以围绕 Git、实用小工具、腾讯云产品对接、UI 强化、语言支持等 14 个主题提交插件,再加上最具娱乐奖,代码最简单奖,设置功能最复杂奖等;近 30 种奖项,超高中奖率;插件只要提交上架,就有 50 元的话费相赠;只要关注 CODING 公众号并转发活动讯息到朋友圈,即可获得手机充值小礼!

参与方式

注册并登陆腾讯云开发者平台(https://dev.tencent.com) -> 点击进入活动页面 -> 点击进行插件的编写与提交(需要选择参与评选的类别)-> 审核无误后即可上架自动参与评选。

赛程时间




 
环信特别奖




基于环信开发一款聊天插件,即有机会获得特别奖,根据作品还将获得环信提供的神秘奖品
更多活动信息,请浏览我们的活动页面。

进入活动页面> 查看全部

2.jpg


由 环信、腾讯云和 CODING 共同举办的 我最喜爱的 Cloud Studio 插件评选大赛正式开始了!在这场比赛里,将会有技术上的碰撞,大牛评委的专业点评,愉快的技术交流,好玩的插件尝试。

6ccda21fgy1fxeim29mncj20ik0e6dn4.jpg

  • 参赛者可以围绕 Git、实用小工具、腾讯云产品对接、UI 强化、语言支持等 14 个主题提交插件,再加上最具娱乐奖,代码最简单奖,设置功能最复杂奖等;
  • 近 30 种奖项,超高中奖率;
  • 插件只要提交上架,就有 50 元的话费相赠;
  • 只要关注 CODING 公众号并转发活动讯息到朋友圈,即可获得手机充值小礼!


参与方式

注册并登陆腾讯云开发者平台https://dev.tencent.com) -> 点击进入活动页面 -> 点击进行插件的编写与提交(需要选择参与评选的类别)-> 审核无误后即可上架自动参与评选。

赛程时间
6ccda21fly1fxejmnr8oej20ow03odfy.jpg

 
环信特别奖
tb16@2x.png

基于环信开发一款聊天插件,即有机会获得特别奖,根据作品还将获得环信提供的神秘奖品
更多活动信息,请浏览我们的活动页面。

进入活动页面>
11
回复

收集基于环信SDK开发的开源项目 开源项目

xiaoyan2015 回复了问题 • 13 人关注 • 11728 次浏览 • 2018-11-21 23:59 • 来自相关话题

4
评论

【开源项目】全国首个开源直播小程序源码 环信公开课 小程序 直播

beyond 发表了文章 • 4026 次浏览 • 2018-07-20 17:30 • 来自相关话题

今天你看直播了吗?拥有10亿微信生态用户的小程序已经成为了继移动互联后的又一个现象级风口,随着微信小程序对外开放实时音视频录制及播放等更多连接能力,小程序与直播强强联合,在各行各业找到了非常多的玩法,小程序直播相比微信直播和APP直播更加简洁、流畅、低延时、多入口等众多优势迅速向商业直播领域及泛娱乐直播领域蔓延。从小游戏、内容付费、工具、大数据、社交电商创业者到传统品牌商们,都在努力搭上小程序直播这辆快车,以免错过微信生态里新的流量洼地。
 





作为一名环信生态圈资深开发者,本着对技术的热衷,对环信的眷恋和对党的忠诚,基于环信即时通讯云写了“直播购物小程序”,目前项目源码已全部免费开放,希望对有需求的企业和开发者提供一个思路和参考。
直播购物小程序源码github地址:https://github.com/YuTongNetworkTechnology/wechat_live/tree/master 
git打不开可直接点下面链接下载


小程序直播demo_2018-06-21.zip







直播购物小程序运行预览图 
 
小程序体验指南(仅需两步):
 
1、下载微信小程序开发工具,下载地址:https://developers.weixin.qq.c ... .html 
 




2、导入源码:将附件的源码解压直接导入 







环信小程序直播技术文档
一、 使用的技术
1、 环信IM直播室。
2、 微信小程序实时音视频播放组件live-player。
3、 推流软件(obs、易推流)等推流。
4、 视频流服务器(UCLOUD、七牛、腾讯)等视频流服务器。
二、 系统使用流程。
1、 视频推流软件将视频流推到流服务器。
2、 打开视频直播demo小程序注册环信账号。
3、 进入软件直播室进行测试。
三、 技术流程及使用的SDk
1、 注册环信账号
打开https://www.easemob.com/ 环信官网,点击右上角注册按钮,选择[注册即时通讯云]




填写对相关信息进行注册





注册成功后进行登录




注:新注册用户需进行账号的认证。
2、 直播应用创建
登录成功点击应用列表选择创建应用




输入应用名称等信息
 





创建成功后点击应用进入





需要注意的是应用的OrgName 和AppName这两个是以后都需要用到的两个参数变量




3、 直播创建
1)在创建直播之前需要对应用进行设置首先需要设置应用的直播流地址
第一步获取应用管理员的Tokencurl -X POST "https://a1.easemob.com/[应用OrgName]/[应用AppName]/token" -d '{"grant_type":"client_credentials","client_id":"[应用client_id]","client_secret":"[应用] client_secret"}'返回格式{
"access_token":"YWMtWY779DgJEeS2h9OR7fw4QgAAAUmO4Qukwd9cfJSpkWHiOa7MCSk0MrkVIco",
"expires_in":5184000,
"application":"c03b3e30-046a-11e4-8ed1-5701cdaaa0e4"












第二步设置直播流地址curl -X POST -H "Authorization: Bearer [管理员Token]" " https://a1.easemob.com/[应用OrgName]/[应用AppName]/liverooms/stream_url -d '{"pc_pull":"[pc拉流地址]","pc_push":"[pc推流地址]","mobile_pull":"[手机拉流地址]","mobile_push":"[手机推流地址]"}'"成功返回格式:{
"action": "post",
"application": "e1a09de0-0e03-11e7-ad8e-a1d913615409",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"pc_pull": true,
"mobile_push": true,
"mobile_pull": true,
"pc_push": true
},
"timestamp": 1494084474885,
"duration": 1,
"organization": "easemob-demo",
"applicationName": "chatdemoui"
}












2)创建主播
点击IM用户





点击注册IM用户





填写用户信息





创建用户的过程同样也可以通过REST API形式进行curl -X POST -i " https://a1.easemob.com/[应用OrgName]/[应用AppName]/users" -d '{"username":"[用户名]","password":"[密码]"}'
注:应用必须为开放注册





将注册的用户添加为主播curl -X POST -H "Authorization: [管理员Token]" https://a1.easemob.com/[应用OrgName]/[应用AppName]/super_admin -d'{"superadmin":"[IM用户名]"}'返回结果示例:{
"action": "post",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"result": "success"
},
"timestamp": 1496236798886,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui"
}












3)创建直播
点击直播





点击新建房间





填写房间信息




创建房间同时也可以使用REST API形式进行详情可以查看http://docs.easemob.com/im/live/server-integration环信官方文档。
4、 小程序demo集成使用
小程序直播购物demo集成官方WebIM SDK详情请查看https://github.com/easemob/webim-weixin-xcx
Demo具体配置如下
打开demo 下sdk配置文件





修改appkey为自己应用的appkey





打开pages/live/index.js修改房间默认拉流地址及直播间房间号





四、 扩展说明
Demo中房间为固定测试房间,实际使用中应获取环信直播的房间信息及房间列表。具体如下:
获取直播间列表:curl -X GET -H "Authorization: Bearer [用户Token]" https://a1.easemob.com/[应用OrgName]/[应用AppName]/liverooms?ongoing=true&limit=[获取数量]&cursor=[游标地址(不填写为充开始查询)]
响应:{
"action": "get",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"params": {
"cursor": [
"ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aW06Y2hhdHJvb206ZWFzZW1vYi1kZW1vI2NoYXRkZW1vdWk6MzE"
],
"ongoing": [
"true"
],
"limit": [
"2"
]
},
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": [
{
"id": "1924",
"chatroom_id": "17177265635330",
"title": "具体了",
"desc": "就咯",
"startTime": 1495779917352,
"endTime": 1495779917352,
"anchor": "wuls",
"gift_count": 0,
"praise_count": 0,
"current_user_count": 8,
"max_user_count": 9,
"status": "ongoing",
"cover_picture_url": "",
"pc_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"pc_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"mobile_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"mobile_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1"
},
{
"id": "1922",
"chatroom_id": "17175003856897",
"title": "香山",
"desc": "随便",
"startTime": 1495777760957,
"endTime": 1495777760957,
"anchor": "sx001",
"gift_count": 0,
"praise_count": 8,
"current_user_count": 1,
"max_user_count": 3,
"status": "ongoing",
"cover_picture_url": "http://127.0.0.1:8080/easemob- ... ot%3B,
"pc_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"pc_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"mobile_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"mobile_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1"
}
],
"timestamp": 1496303336669,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui",
"cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aW06Y2hhdHJvb206ZWFzZW1vYi1kZW1vI2NoYXRkZW1vdWk6NDk",
"count": 2
}












获取直播间详情:curl -X GET -H "Authorization: Bearer [用户Token]" " https://a1.easemob.com/[应用OrgName]/[应用AppName]/[房间id]/status"响应:{
"action": "get",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"liveRoomID": "1946",
"status": "ongoing"
},
"timestamp": 1496234759930,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui",
"count": 0
}














 
使用环信直播购物小程序遇到任何问题欢迎跟帖讨论。 查看全部
今天你看直播了吗?
拥有10亿微信生态用户的小程序已经成为了继移动互联后的又一个现象级风口,随着微信小程序对外开放实时音视频录制及播放等更多连接能力,小程序与直播强强联合,在各行各业找到了非常多的玩法,小程序直播相比微信直播和APP直播更加简洁、流畅、低延时、多入口等众多优势迅速向商业直播领域及泛娱乐直播领域蔓延。从小游戏、内容付费、工具、大数据、社交电商创业者到传统品牌商们,都在努力搭上小程序直播这辆快车,以免错过微信生态里新的流量洼地。
 
微信图片_20180725162426.jpg


作为一名环信生态圈资深开发者,本着对技术的热衷,对环信的眷恋和对党的忠诚,基于环信即时通讯云写了“直播购物小程序”,目前项目源码已全部免费开放,希望对有需求的企业和开发者提供一个思路和参考。
直播购物小程序源码github地址:https://github.com/YuTongNetworkTechnology/wechat_live/tree/master 
git打不开可直接点下面链接下载



预览图.jpg

直播购物小程序运行预览图 
 
小程序体验指南(仅需两步):
 
1、下载微信小程序开发工具,下载地址:https://developers.weixin.qq.c ... .html 
 
Catch9A07(07-20-17-38-30).jpg

2、导入源码:将附件的源码解压直接导入 


Catch1C69(07-20-17-38-30).jpg


环信小程序直播技术文档
一、 使用的技术
1、 环信IM直播室。
2、 微信小程序实时音视频播放组件live-player。
3、 推流软件(obs、易推流)等推流。
4、 视频流服务器(UCLOUD、七牛、腾讯)等视频流服务器。
二、 系统使用流程。
1、 视频推流软件将视频流推到流服务器。
2、 打开视频直播demo小程序注册环信账号。
3、 进入软件直播室进行测试。
三、 技术流程及使用的SDk
1、 注册环信账号
打开https://www.easemob.com/ 环信官网,点击右上角注册按钮,选择[注册即时通讯云]
1.png

填写对相关信息进行注册

2.png

注册成功后进行登录
3.png

注:新注册用户需进行账号的认证。
2、 直播应用创建
登录成功点击应用列表选择创建应用
4.png

输入应用名称等信息
 

5.png

创建成功后点击应用进入

6.png

需要注意的是应用的OrgName 和AppName这两个是以后都需要用到的两个参数变量
7.png

3、 直播创建
1)在创建直播之前需要对应用进行设置首先需要设置应用的直播流地址
第一步获取应用管理员的Token
curl -X POST "https://a1.easemob.com/[应用OrgName]/[应用AppName]/token" -d '{"grant_type":"client_credentials","client_id":"[应用client_id]","client_secret":"[应用] client_secret"}'
返回格式
{
"access_token":"YWMtWY779DgJEeS2h9OR7fw4QgAAAUmO4Qukwd9cfJSpkWHiOa7MCSk0MrkVIco",
"expires_in":5184000,
"application":"c03b3e30-046a-11e4-8ed1-5701cdaaa0e4"












第二步设置直播流地址
curl -X POST -H "Authorization: Bearer [管理员Token]"  " https://a1.easemob.com/[应用OrgName]/[应用AppName]/liverooms/stream_url -d '{"pc_pull":"[pc拉流地址]","pc_push":"[pc推流地址]","mobile_pull":"[手机拉流地址]","mobile_push":"[手机推流地址]"}'"
成功返回格式:
{
"action": "post",
"application": "e1a09de0-0e03-11e7-ad8e-a1d913615409",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"pc_pull": true,
"mobile_push": true,
"mobile_pull": true,
"pc_push": true
},
"timestamp": 1494084474885,
"duration": 1,
"organization": "easemob-demo",
"applicationName": "chatdemoui"
}












2)创建主播
点击IM用户

8.png

点击注册IM用户

9.png

填写用户信息

10.png

创建用户的过程同样也可以通过REST API形式进行
curl -X POST -i " https://a1.easemob.com/[应用OrgName]/[应用AppName]/users" -d '{"username":"[用户名]","password":"[密码]"}'

注:应用必须为开放注册

11.png

将注册的用户添加为主播
curl -X POST -H "Authorization: [管理员Token]"  https://a1.easemob.com/[应用OrgName]/[应用AppName]/super_admin -d'{"superadmin":"[IM用户名]"}'
返回结果示例:
{
"action": "post",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"result": "success"
},
"timestamp": 1496236798886,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui"
}












3)创建直播
点击直播

12.png

点击新建房间

13.png

填写房间信息
14.png

创建房间同时也可以使用REST API形式进行详情可以查看http://docs.easemob.com/im/live/server-integration环信官方文档。
4、 小程序demo集成使用
小程序直播购物demo集成官方WebIM SDK详情请查看https://github.com/easemob/webim-weixin-xcx
Demo具体配置如下
打开demo 下sdk配置文件

15.png

修改appkey为自己应用的appkey

16.png

打开pages/live/index.js修改房间默认拉流地址及直播间房间号

17.png

四、 扩展说明
Demo中房间为固定测试房间,实际使用中应获取环信直播的房间信息及房间列表。具体如下:
获取直播间列表:
curl -X GET -H "Authorization: Bearer  [用户Token]"  https://a1.easemob.com/[应用OrgName]/[应用AppName]/liverooms?ongoing=true&limit=[获取数量]&cursor=[游标地址(不填写为充开始查询)]

响应:
{
"action": "get",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"params": {
"cursor": [
"ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aW06Y2hhdHJvb206ZWFzZW1vYi1kZW1vI2NoYXRkZW1vdWk6MzE"
],
"ongoing": [
"true"
],
"limit": [
"2"
]
},
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": [
{
"id": "1924",
"chatroom_id": "17177265635330",
"title": "具体了",
"desc": "就咯",
"startTime": 1495779917352,
"endTime": 1495779917352,
"anchor": "wuls",
"gift_count": 0,
"praise_count": 0,
"current_user_count": 8,
"max_user_count": 9,
"status": "ongoing",
"cover_picture_url": "",
"pc_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"pc_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"mobile_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"mobile_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1"
},
{
"id": "1922",
"chatroom_id": "17175003856897",
"title": "香山",
"desc": "随便",
"startTime": 1495777760957,
"endTime": 1495777760957,
"anchor": "sx001",
"gift_count": 0,
"praise_count": 8,
"current_user_count": 1,
"max_user_count": 3,
"status": "ongoing",
"cover_picture_url": "http://127.0.0.1:8080/easemob- ... ot%3B,
"pc_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"pc_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"mobile_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"mobile_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1"
}
],
"timestamp": 1496303336669,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui",
"cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aW06Y2hhdHJvb206ZWFzZW1vYi1kZW1vI2NoYXRkZW1vdWk6NDk",
"count": 2
}












获取直播间详情:
curl -X GET -H "Authorization: Bearer [用户Token]" " https://a1.easemob.com/[应用OrgName]/[应用AppName]/[房间id]/status"
响应:
{
"action": "get",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"liveRoomID": "1946",
"status": "ongoing"
},
"timestamp": 1496234759930,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui",
"count": 0
}














 
使用环信直播购物小程序遇到任何问题欢迎跟帖讨论。
19
评论

【新手快速入门】集成环信常见问题+解决方案汇总 常见问题

dujiepeng 发表了文章 • 18351 次浏览 • 2017-05-22 15:51 • 来自相关话题

   这里整理了集成环信的常见问题和一些功能的实现思路,希望能帮助到大家。感谢热心的开发者贡献,大家在观看过程中有不明白的地方欢迎直接跟帖咨询。
 
ios篇
APNs证书创建和上传到环信后台头像昵称的简述和处理方案音视频离线推送Demo实现环信服务器聊天记录保存多久?离线收不到好友请求IOS中环信聊天窗口如何实现文件发送和预览的功能ios集成常见问题环信推送的一些常见问题实现名片|红包|话题聊天室等自定义cell
 
Android篇
Android sdk 的两种导入方式环信3.0SDK集成小米推送教程EaseUI库中V4、v7包冲突解决方案Android EaseUI里的百度地图替换为高德地图android扩展消息(名片集成)关于会话列表的置顶聊天java.lang.UnsatisfiedLinkError: 的问题android 端 app 后台被杀死收不到消息的解决方案
昵称头像篇
android中如何显示开发者服务器上的昵称和头像 Android中显示头像(接上一篇文章看)环信(Android)设置头像和昵称的方法(最简单暴力的基于环信demo的集成)IOS中如何显示开发者服务器上的昵称和头像【环信公开课第12期视频回放】-所有关于环信IM昵称头像的问题听这课就够了
 
直播篇
一言不合你就搞个直播APP
 
客服集成
IM-SDK和客服SDK并存开发指南—Android篇IM-SDK和客服SDK并存开发指南—iOS篇
 
开源项目
Android简版demoios简版demo凡信2.0:超仿微信的开源项目 凡信3.0:携直播和红包而来高仿微信:Github 3,515 Star方圆十里:环信编程大赛冠军项目泛聊:定一个小目标写一个QQSlack聊天机器人:一天时间做一个聊天机器人TV视频通话:在电视上视频通话视频通话:Android手机视频通话酷信:ios高仿微信公众号助手:与订阅用户聊天沟通
 
持续更新ing...小伙伴们还有什么想知道欢迎跟帖提出。
  查看全部
   这里整理了集成环信的常见问题和一些功能的实现思路,希望能帮助到大家。感谢热心的开发者贡献,大家在观看过程中有不明白的地方欢迎直接跟帖咨询。
 
ios篇

 
Android篇

昵称头像篇

 
直播篇
  1. 一言不合你就搞个直播APP

 
客服集成
  1. IM-SDK和客服SDK并存开发指南—Android篇
  2. IM-SDK和客服SDK并存开发指南—iOS篇

 
开源项目

 
持续更新ing...小伙伴们还有什么想知道欢迎跟帖提出。
 
0
评论

微信后台基于时间序的海量数据冷热分级架构设计实践 架构 微信

beyond 发表了文章 • 810 次浏览 • 2017-06-27 16:37 • 来自相关话题

   微信的后台数据存储随着微信产品特性的演进,经历了数次的架构改造,才形成如今成熟的大规模分布式存储系统,有条不紊的管理着由数千台异构机型组成的机器集群,得以支撑每天千万亿级的访问、键值以及 PB 级的数据。

   作为以手机为平台的移动社交应用,微信内大部分业务生成的数据是有共性可言的:数据键值带有时间戳信息,并且单用户数据随着时间在不断的生成。我们将这类数据称为基于时间序的数据。比如朋友圈中的发表,或者移动支付的账单流水等业务生成的数据都满足这样的特征。基于时间序的数据都天然带有冷热分明属性――这是由手机的物理特性决定的,它的尺寸有限的屏幕所展示的数据只能分屏,通过手指的滑动,平滑而又连续的沿时间轴依次访问――通常是由最新生成的数据,慢慢回溯到较早前的数据。同时朋友圈等业务都是信息读扩散的应用场景,这就意味着它们生成的后台数据具有读多写少的鲜明特征。
在微信的实际应用场景中,这类数据的主要特点包括:数据量大、访问量大、重要程度高等。这些特点在现网的实际运营过程中,给我们带来了非常大的挑战,主要包括:数据量大,需求的存储容量高――基于时间序的数据通常不会删除,而是随着时间不断积累,数据量达到 PB 级别,相应需要的存储空间也与日俱增;访问量大,节日效应明显――基于时间序的数据往往是热点业务生成的数据,它们的访问量居高不下,基本维持在每分钟数十亿次的级别。尤其是在节日期间,瞬发访问量更可达平日的三至五倍;重要性高,用户感知明显,数据一旦丢失,导致用户不能正常使用产品,并因此而转化成的投诉率高。

   通过堆机器来横向扩展存储自然可以应对如上的各种挑战,然而在成本预算紧张的前提下,机器数目是有限的。在这种情况下,基于时间序的海量数据的冷热分级架构便应运而生。该架构正是为了应对后台日益膨胀的这类数据,本着充分利用机器资源,发挥各种硬件介质特长的原则,结合数据的冷热分明、读多写少的访问特征而开发和设计出来的。它基于数据分层的理念,根据不同时间段的数据在访问热度和数据量上的差异,定制不同的服务策略,在纵向上扩展存储的边界。横向扩展存储是易于理解的,通过向原集群中增加相同类型的机器――其中必然涉及到一轮历史数据的迁移――最终新旧机器负载均衡,彼此之间并无差异的对外提供服务。在这种方案下,数据横向流动,系统一视同仁的对待,显然并无因地制宜思想的容身之所。而纵向扩展存储的架构便提供了这样一种思路:

   对热点数据,数据量少,但承担的访问流量大,我们当然是希望它们能常驻内存,因此系统提供了有强一致保证的内存层,在应对突发流量时,也可在不涉及历史数据迁移的前提下,单独、动态的快速扩展内存层。

   对历史数据,数据存量大,但承担的访问量非常有限,我们当然是不希望用昂贵的固态硬盘来存储它们,因此,系统提供了廉价的机械盘层,并且有一套透明的冷数据剥离和批量下沉的流程,将存储层中历史数据源源不断的抽离到机械盘层。

   通过这样的一种纵向分层、单独扩展的思路,即为我们系统提供了极大的灵活性,解决了节日期间存储层面临的内存瓶颈,以从长远的角度为我们缓解了成本压力,解决了存储层面临的磁盘容量瓶颈。

   当然一套成功的大型分布式系统仅有这些是不够的,还必须包括数据多副本复制策略以及分区算法等,也要有能应对复杂的现网运营环境的能力。我们结合各层的服务特点,制订了相对应的数据强一致算法,如内存层通过版本号控制来保证与存储层的完全一致,存储层通过 Paxos Group 实现多副本容灾,而机械盘层则通过串行写来保证。我们同时也实现了自己的去中心化的数据路由算法,确保了数据和流量的均匀分布,并且保证这种特性在横向扩展后依然成立。

   通过如上工作的努力,环环相扣,我们的基于时间序的海量数据的冷热分层架构成功的应对了 PB 级数据、千亿级访问以及万亿级键值带来的挑战。

系统设计
数据模型
本文提及的海量数据的冷热分级架构是专门服务于基于时间序的数据,它们主要特征为:

a). 数据键值带有时间戳信息 ;

b). 单用户数据随着时间在不断的生成。

   我们设计的架构强依赖于特性 a),各个环节基本上是依赖于键值中的时间戳来分发数据或者进行数据排序的。至于键值中的时间戳如何生成、全局是否维持统一时间、如何维持等则不在本文的讨论范围,通常这由前端的业务特性以及后台的时间服务器策略决定的。

   而特性 b) 则保证了本架构的必要性、实用性。如果数据规模有限,以用户的账户信息举例,它就像我们日常生活中的户口本,它只有一份,对单用户而言不会新增。则我们通常用固定的机器集群存储就可以,并且鲜有变更。而我们要处理的是用户的日记本、或者记账簿,它们每天都在不断生成新数据。

我们以现网某个集群的实例情况举例,说明下此类业务数据有如下的特点:

1.、数据量大,PB 级数据,万亿级键值,并且在源源不断的生成中,然而新生成的数据相较于历史存量数据占比小。下图展示了该集群数据在各时间段的一个占比情况。




2、访问量大,峰值可达每分钟数十亿次访问,尤其是在节日期间,用户高涨的热情更可以转化成平日三至五倍的访问量。同时具有冷热分明、读多写少 (读写比例甚至可达 100:1) 的访问特征,比如节日期间倍增的访问通常是对节日期间生成的新增数据的访问。下图展示了该集群访问在各时间段的一个占比情况。




3、数据安全性要求高,这类数据通常是用户感知敏感数据,一旦丢失,转化成的用户投诉率高。




存储层





数据强一致性保证
 
业务要求系统必须保证在数据的多份副本之间保持强一致性。――这是一个历久弥新的挑战。我们将分内存层、存储层、机械硬盘层分别来考虑数据的强一致性维持。
 
强一致缓存
 
正如前文描述,内存层作为一种强一致性分布式缓存,它完全是向存储层对齐的,自身无法判别数据有效性,本身多副本之间也没有交互的必要。它对前端而言是只读的,所有的写请求并不通过它,它只能算是存储层中数据的一个视图。所以它对前端数据有效性的承诺完全是依赖于存储层的正确性的。
 
Paxos Group
 
我们基于 Paxos Group 实现了存储层的数据一致性,通过采用无租约的方式,使得系统在保证强一致性的前提下达到了最大的可用性。Paxos 算法是由 Lesile Lamport 在论文中首提的,它唯一的作用是在多个参与者之间唯一的确定一个常量值。――这点同分布式存储没有直接关联的。我们在 Paxos 算法的基础上,设计出基于消息驱动的 Paxos Log 组件――每一条操作日志都要 Paxos 算法来确定,再进一步实现了基于 Paxos Log 的强一致性读写。

Paxos Group 因为采用了无主模型,组内所有机器在任一时刻都处于相同的地位。Paxos 算法本质是个多副本同步写算法,当且仅当系统中的多数派都接受相同值后,才会返回写成功。因此任意单一节点的失效,都不会出现系统的不可用。

强一致性写协议的主要问题来源于 Paxos 算法本身,因为要确保数据被系统内的多数派接受,需要进行多阶段的交互。我们采用如下的方法,解决了 paxos 算法写过程中出现的问题:基于 fast accept 协议优化了写算法,降低了写盘量以及协议消息发送、接收次数,最终实现了写耗时和失败的降低;基于随机避让、限制单次 Paxos 写触发 Prepare 的次数等方法,解决了 Paxos 中的活锁问题。

强一致性读协议本身和 Paxos 算法并没有太大的关系,只要确认多副本之间的多数派,即可获取到最新的数据。我们通过广播的方式获取到集群中多数机器(包含自身)的 paxos log 的状态,然后判断本机数据的有效性。

当系统中的单机节点失效,数据完全丢失的时候――这种情况是可以算是 Paxos 算法的盲区,因为该算法基于所有的参与者都不会违背自己曾经的承诺,即拜占庭失败而导致的数据不一致。――而这种情况在现网运营中可谓是常态,因此,我们引入了 Learner Only 模式。在该模式下故障机只接收已提交的数据,而不参与 Paxos 协议的写过程,意即不会因数据丢失而违背任何承诺。然后通过异步 catch up 和全量数据校验快速从其它副本中恢复数据。

为了防止多节点同时失效,我们将数据的多副本分布在不同园区的机器上。园区是同一个城市不同数据中心的概念。如此,我们的结构足以应对单数据中心完全隔离级别的灾难。
 
串行写入
 
因为对客户端透明,冷数据下沉流程作为机械硬盘层的唯一写者,则该层的数据一致性是易于实现的。我们通过三副本串行写入、全部提交才算成功的方式来实现了多副本之间的数据一致性。

作为补充,冷数据集群为数据块增加了 CRC 校验和一致性恢复队列,当单机数据不可用 (丢失或者损坏) 时,首先客户端会跳转到其它备份中读 (三机同时对外提供读服务),一致性恢复队列会异步的从其它备份数据块中恢复本机数据。

因为采用了 No Raid 方式组织的盘组,并且同组机器间盘级别数据文件一致,在单盘故障引发数据丢失时,只要从其它机器相同序盘中传输数据文件即可。

数据分区
 
静态映射表
 
数据分区的主要目的是为了确保同层机器间的负载均衡,并且当机器规模发生变化后,在最终仍然可以达到负载均衡的一种状态。

经典的一致性哈希算法的初衷是为了健壮分布式缓存,基于运行时动态的计算哈希值和虚拟节点来进行寻址。数据存储与分布式缓存的不同在于,存储必须保证数据映射的单调性,而缓存则无此要求,所以经典的一致性哈希通常会使用机器 IP 等作为参数来进行哈希,这样造成的结果一方面是数据的落点时而发生改变,一方面是负载通常不均衡。因此我们改造了此算法。

我们通过预计算虚拟节点随机数的方法,生成了割环点同实体机器之间的映射表。该映射表最多可支持一千组的集群规模,满足在任意组数情况下,实体机器间割段长度维持差异在 2% 以内;并且增加任意组数 (总组数上限不超过一千组),变动后的实体机器间的割段长度依然维持差异在 2% 以内。我们将此映射表硬编码,在运行时避免了计算的过程,数据根据键值哈希值寻址时,只要经过一次二分查找即可获取到对应的实体机器的编号。我们在内存层、存储层以及机械硬盘层都采用了这个映射表,保证了数据在各层路由算法的一致。在工程实现方面,我们可以合理使用这个特性来批量合并请求,以降低资源消耗,这在稍后的章节会有详细描述。
 
组内均衡
 
组是数据分区的独立单元,是虚拟节点对应的实体单位。组之间是互相独立的。每组由多台物理机器组成,这是 Paxos Group 生效的基本单位。一份数据包括的多份副本分别散落在组内的各台机器上。为了在组内机器上保证负载均衡,我们同样设计了一套算法,规定了数据副本之间的访问优先级,前端会依优先级逐一的请求数据,只要成功获取,即中断这个过程。然后我们再将副本按优先级均匀的散落在组内机器上,如此即可实现组内负载的均衡。
 
数据迁移
 
静态映射表是非常灵活的,在不达到组数上限的情况下,可以任意的增加一组或者多组机器。当然这个过程中一些数据的路由映射发生了改变,则就涉及到了历史数据的挪腾。为了在挪腾的过程中不影响服务,保证数据依然可读可写,我们开发出了对前端透明的,基于迁移标志位,通过数据双写和异步挪数据的方式实现的安全的、可回退的数据迁移流程。
 
最小不变块
 
存储层和机械硬盘层通过冷数据链接耦合在了一起。因为两层使用了相同的映射表,那么当存储层因扩容而发生迁移时,那么冷数据链接无疑也要重新寻址,进行一轮重新定位。如果我们以单键值为粒度记录冷数据链接和进行冷数据下沉,那么在万亿键值的语境下,效率无疑是低下。因此我们设计了最小不变块的算法,通过两阶段哈希,使用中间的哈希桶聚集数据,将数据键值和冷数据存储层的机器路由隔离开来。通过该算法,我们可以实现:批量的转存冷数据、热数据存储层批量的以块 (block) 为单位记录冷数据链接、当热数据存储层发生扩容时,块 (block) 内的数据不因扩容被打散掉,而可以整体的迁移到新目标机上。
 
工程实现
 
糟糕的工程实现可以毁掉一个完美的系统设计,因此,如何在工程实现的过程中,通过技术的手段,提升系统的表现,同样值得重视。
 
高效缓存
 
内存层的设计严重依赖存储层数据版本号的高效获取,那自然是版本号请求全落在内存中就可以了。因此,针对这种情况我们为定长的版本号设计了一套极简的、轻量的、行之有效的缓存――内存容量不足以支撑版本号全缓存。




它的数据结构只是一个二维数组,一维用来构建 hash 链,一维用来实现 LRU 链。每次读或者写都需要通过数组内数据的挪动,来进行更新。如此一来,我们就通过千万级数目的 LRU 链群,实现了缓存整体的 LRU 淘汰。它具有定长,可共享内存搭载,进程重启不丢失、内存使用率高等优点。
 
批量操作
 
对系统服务器而言,前端访问过来的某个请求,其对应的逻辑操作都是串行的,我们自然可以梳理这个串行流程中的 CPU 消耗点进行优化。然而当主要的瓶颈被逐渐的消灭掉后,CPU 消耗点变得分散,优化效果就变得微乎其微了。因此,我们只能寻找其它突破点。

我们发现在存储引擎、一致性协议算法的实现流程中,逻辑操作步骤多,涉及到网络交互,硬盘读写等过程。因此,我们决定合并不同请求中的相同步骤,实现批量化操作,极大的优化了 CPU 消耗。

合并的代价即是耗时略有增加,我们通过快慢分离,只针对热点数据请求中的逻辑操作进行合并,去掉了耗时中的不稳定因子,减少了耗时抖动。
 
请求合并
 
既然单机的逻辑操作性能已经得到了极大的提升,那么前后端的网络交互阶段,包括接入层的打包解包、协议处理等环节,成为了资源的主要消耗点。参考批量操作的经验,我们同样使用批量化的技术来优化性能――即将后台访问过来的单条请求 (Get) 在内存层聚合成一次批量请求 (Batch Get)。
 
路由收敛
 
因为每个数据都是根据键值单独进行路由的,如果要进行请求合并,我们就必须确保同一个批量请求内的数据,都会寻址到相同的 Paxos Group 上。因此,我们必须在内存层将落到同一台存储机器上的 Get 请求聚合起来。我们首先在内存层和存储层采用了相同的路由算法,然后将内存层的组数同存储层的组数进行对齐,来完成了这一目标。






相关工作
 
在设计的阶段,我们充分的调研了业界的各类方案,大到系统的整体架构,小到具体的技术点。各种方案自有应用场景、各有千秋,不能单纯以好坏区别,我们同样基于自己的业务场景,谨慎的选择合适的方案,或者弃而不用。在此尽量叙述。

处理 SNS 类业务生成的数据,业界有多种的冷热分离架构可以参考。我们以 Facebook 的 Cold Storage 系统举例而言,它也是基于冷热分层的想法,设计出了服务它们照片业务数据的存储方案。不同的是它采用了软硬件结合的方法,一方面定制专门的服务器(包括硬盘、电源等)和数据中心,一方面降低冷数据的备份数、增加纠删码等手段。

然而它们的经验我们是无法彻底套用的,主要两种原因:我们可使用的机器机型是固定的,不存在自己定制硬件的条件。同时它处理的是照片这种大 value 的数据。而我们基本上是文本这种类型的小 value 数据。从前文提及的 TB 访问量角度来看,它们处理的数据是容量瓶颈的,而我们处理的是 IO 瓶颈的,可以算是不太冷的冷数据带来的挑战。所以,我们只能实现自己的冷数据管理策略。

同样,业界有诸多关于如何实现数据一致性的方案。包括我们微信自研的 Quorum 协议,它是一种 NWR 协议,采用异步同步的方式实现数据多副本。即然是异步同步,那在多副本达到最终一致,必然存在一个时间差,那么在单机出现离线的情况下,就会有一定概率导致数据的不可用。而我们追求的是在单点故障下,所有的数据都保证强可用性。

因此,我们采用了无主的去中心化的 Paxos Group 实现了这一目标,其中非租约是 PaxosStore 架构的一个创新亮点。在故障时通常系统是抖动的,会有时断时续的状况,常见的租约做法在这种场景下容易出现反复切换主机而导致长期不可用,而 PaxosStore 的非租约结构能够轻松应对,始终提供良好的服务。PaxosStore 核心代码正在整理开源当中,预计四季度会正式发布,同时该项目的底层框架也基于我们已开源的协程库 github.com/libco。
 
转自“计算机与网络安全”,作者杨平安 查看全部
   微信的后台数据存储随着微信产品特性的演进,经历了数次的架构改造,才形成如今成熟的大规模分布式存储系统,有条不紊的管理着由数千台异构机型组成的机器集群,得以支撑每天千万亿级的访问、键值以及 PB 级的数据。

   作为以手机为平台的移动社交应用,微信内大部分业务生成的数据是有共性可言的:数据键值带有时间戳信息,并且单用户数据随着时间在不断的生成。我们将这类数据称为基于时间序的数据。比如朋友圈中的发表,或者移动支付的账单流水等业务生成的数据都满足这样的特征。基于时间序的数据都天然带有冷热分明属性――这是由手机的物理特性决定的,它的尺寸有限的屏幕所展示的数据只能分屏,通过手指的滑动,平滑而又连续的沿时间轴依次访问――通常是由最新生成的数据,慢慢回溯到较早前的数据。同时朋友圈等业务都是信息读扩散的应用场景,这就意味着它们生成的后台数据具有读多写少的鲜明特征。
  1. 在微信的实际应用场景中,这类数据的主要特点包括:数据量大、访问量大、重要程度高等。这些特点在现网的实际运营过程中,给我们带来了非常大的挑战,主要包括:
  2. 数据量大,需求的存储容量高――基于时间序的数据通常不会删除,而是随着时间不断积累,数据量达到 PB 级别,相应需要的存储空间也与日俱增;
  3. 访问量大,节日效应明显――基于时间序的数据往往是热点业务生成的数据,它们的访问量居高不下,基本维持在每分钟数十亿次的级别。尤其是在节日期间,瞬发访问量更可达平日的三至五倍;
  4. 重要性高,用户感知明显,数据一旦丢失,导致用户不能正常使用产品,并因此而转化成的投诉率高。


   通过堆机器来横向扩展存储自然可以应对如上的各种挑战,然而在成本预算紧张的前提下,机器数目是有限的。在这种情况下,基于时间序的海量数据的冷热分级架构便应运而生。该架构正是为了应对后台日益膨胀的这类数据,本着充分利用机器资源,发挥各种硬件介质特长的原则,结合数据的冷热分明、读多写少的访问特征而开发和设计出来的。它基于数据分层的理念,根据不同时间段的数据在访问热度和数据量上的差异,定制不同的服务策略,在纵向上扩展存储的边界。横向扩展存储是易于理解的,通过向原集群中增加相同类型的机器――其中必然涉及到一轮历史数据的迁移――最终新旧机器负载均衡,彼此之间并无差异的对外提供服务。在这种方案下,数据横向流动,系统一视同仁的对待,显然并无因地制宜思想的容身之所。而纵向扩展存储的架构便提供了这样一种思路:

   对热点数据,数据量少,但承担的访问流量大,我们当然是希望它们能常驻内存,因此系统提供了有强一致保证的内存层,在应对突发流量时,也可在不涉及历史数据迁移的前提下,单独、动态的快速扩展内存层。

   对历史数据,数据存量大,但承担的访问量非常有限,我们当然是不希望用昂贵的固态硬盘来存储它们,因此,系统提供了廉价的机械盘层,并且有一套透明的冷数据剥离和批量下沉的流程,将存储层中历史数据源源不断的抽离到机械盘层。

   通过这样的一种纵向分层、单独扩展的思路,即为我们系统提供了极大的灵活性,解决了节日期间存储层面临的内存瓶颈,以从长远的角度为我们缓解了成本压力,解决了存储层面临的磁盘容量瓶颈。

   当然一套成功的大型分布式系统仅有这些是不够的,还必须包括数据多副本复制策略以及分区算法等,也要有能应对复杂的现网运营环境的能力。我们结合各层的服务特点,制订了相对应的数据强一致算法,如内存层通过版本号控制来保证与存储层的完全一致,存储层通过 Paxos Group 实现多副本容灾,而机械盘层则通过串行写来保证。我们同时也实现了自己的去中心化的数据路由算法,确保了数据和流量的均匀分布,并且保证这种特性在横向扩展后依然成立。

   通过如上工作的努力,环环相扣,我们的基于时间序的海量数据的冷热分层架构成功的应对了 PB 级数据、千亿级访问以及万亿级键值带来的挑战。

系统设计
数据模型
本文提及的海量数据的冷热分级架构是专门服务于基于时间序的数据,它们主要特征为:

a). 数据键值带有时间戳信息 ;

b). 单用户数据随着时间在不断的生成。

   我们设计的架构强依赖于特性 a),各个环节基本上是依赖于键值中的时间戳来分发数据或者进行数据排序的。至于键值中的时间戳如何生成、全局是否维持统一时间、如何维持等则不在本文的讨论范围,通常这由前端的业务特性以及后台的时间服务器策略决定的。

   而特性 b) 则保证了本架构的必要性、实用性。如果数据规模有限,以用户的账户信息举例,它就像我们日常生活中的户口本,它只有一份,对单用户而言不会新增。则我们通常用固定的机器集群存储就可以,并且鲜有变更。而我们要处理的是用户的日记本、或者记账簿,它们每天都在不断生成新数据。

我们以现网某个集群的实例情况举例,说明下此类业务数据有如下的特点:

1.、数据量大,PB 级数据,万亿级键值,并且在源源不断的生成中,然而新生成的数据相较于历史存量数据占比小。下图展示了该集群数据在各时间段的一个占比情况。
001.jpg

2、访问量大,峰值可达每分钟数十亿次访问,尤其是在节日期间,用户高涨的热情更可以转化成平日三至五倍的访问量。同时具有冷热分明、读多写少 (读写比例甚至可达 100:1) 的访问特征,比如节日期间倍增的访问通常是对节日期间生成的新增数据的访问。下图展示了该集群访问在各时间段的一个占比情况。
002.jpg

3、数据安全性要求高,这类数据通常是用户感知敏感数据,一旦丢失,转化成的用户投诉率高。
003.jpg

存储层

004.jpg

数据强一致性保证
 
业务要求系统必须保证在数据的多份副本之间保持强一致性。――这是一个历久弥新的挑战。我们将分内存层、存储层、机械硬盘层分别来考虑数据的强一致性维持。
 
强一致缓存
 
正如前文描述,内存层作为一种强一致性分布式缓存,它完全是向存储层对齐的,自身无法判别数据有效性,本身多副本之间也没有交互的必要。它对前端而言是只读的,所有的写请求并不通过它,它只能算是存储层中数据的一个视图。所以它对前端数据有效性的承诺完全是依赖于存储层的正确性的。
 
Paxos Group
 
我们基于 Paxos Group 实现了存储层的数据一致性,通过采用无租约的方式,使得系统在保证强一致性的前提下达到了最大的可用性。Paxos 算法是由 Lesile Lamport 在论文中首提的,它唯一的作用是在多个参与者之间唯一的确定一个常量值。――这点同分布式存储没有直接关联的。我们在 Paxos 算法的基础上,设计出基于消息驱动的 Paxos Log 组件――每一条操作日志都要 Paxos 算法来确定,再进一步实现了基于 Paxos Log 的强一致性读写。

Paxos Group 因为采用了无主模型,组内所有机器在任一时刻都处于相同的地位。Paxos 算法本质是个多副本同步写算法,当且仅当系统中的多数派都接受相同值后,才会返回写成功。因此任意单一节点的失效,都不会出现系统的不可用。

强一致性写协议的主要问题来源于 Paxos 算法本身,因为要确保数据被系统内的多数派接受,需要进行多阶段的交互。我们采用如下的方法,解决了 paxos 算法写过程中出现的问题:基于 fast accept 协议优化了写算法,降低了写盘量以及协议消息发送、接收次数,最终实现了写耗时和失败的降低;基于随机避让、限制单次 Paxos 写触发 Prepare 的次数等方法,解决了 Paxos 中的活锁问题。

强一致性读协议本身和 Paxos 算法并没有太大的关系,只要确认多副本之间的多数派,即可获取到最新的数据。我们通过广播的方式获取到集群中多数机器(包含自身)的 paxos log 的状态,然后判断本机数据的有效性。

当系统中的单机节点失效,数据完全丢失的时候――这种情况是可以算是 Paxos 算法的盲区,因为该算法基于所有的参与者都不会违背自己曾经的承诺,即拜占庭失败而导致的数据不一致。――而这种情况在现网运营中可谓是常态,因此,我们引入了 Learner Only 模式。在该模式下故障机只接收已提交的数据,而不参与 Paxos 协议的写过程,意即不会因数据丢失而违背任何承诺。然后通过异步 catch up 和全量数据校验快速从其它副本中恢复数据。

为了防止多节点同时失效,我们将数据的多副本分布在不同园区的机器上。园区是同一个城市不同数据中心的概念。如此,我们的结构足以应对单数据中心完全隔离级别的灾难。
 
串行写入
 
因为对客户端透明,冷数据下沉流程作为机械硬盘层的唯一写者,则该层的数据一致性是易于实现的。我们通过三副本串行写入、全部提交才算成功的方式来实现了多副本之间的数据一致性。

作为补充,冷数据集群为数据块增加了 CRC 校验和一致性恢复队列,当单机数据不可用 (丢失或者损坏) 时,首先客户端会跳转到其它备份中读 (三机同时对外提供读服务),一致性恢复队列会异步的从其它备份数据块中恢复本机数据。

因为采用了 No Raid 方式组织的盘组,并且同组机器间盘级别数据文件一致,在单盘故障引发数据丢失时,只要从其它机器相同序盘中传输数据文件即可。

数据分区
 
静态映射表
 
数据分区的主要目的是为了确保同层机器间的负载均衡,并且当机器规模发生变化后,在最终仍然可以达到负载均衡的一种状态。

经典的一致性哈希算法的初衷是为了健壮分布式缓存,基于运行时动态的计算哈希值和虚拟节点来进行寻址。数据存储与分布式缓存的不同在于,存储必须保证数据映射的单调性,而缓存则无此要求,所以经典的一致性哈希通常会使用机器 IP 等作为参数来进行哈希,这样造成的结果一方面是数据的落点时而发生改变,一方面是负载通常不均衡。因此我们改造了此算法。

我们通过预计算虚拟节点随机数的方法,生成了割环点同实体机器之间的映射表。该映射表最多可支持一千组的集群规模,满足在任意组数情况下,实体机器间割段长度维持差异在 2% 以内;并且增加任意组数 (总组数上限不超过一千组),变动后的实体机器间的割段长度依然维持差异在 2% 以内。我们将此映射表硬编码,在运行时避免了计算的过程,数据根据键值哈希值寻址时,只要经过一次二分查找即可获取到对应的实体机器的编号。我们在内存层、存储层以及机械硬盘层都采用了这个映射表,保证了数据在各层路由算法的一致。在工程实现方面,我们可以合理使用这个特性来批量合并请求,以降低资源消耗,这在稍后的章节会有详细描述。
 
组内均衡
 
组是数据分区的独立单元,是虚拟节点对应的实体单位。组之间是互相独立的。每组由多台物理机器组成,这是 Paxos Group 生效的基本单位。一份数据包括的多份副本分别散落在组内的各台机器上。为了在组内机器上保证负载均衡,我们同样设计了一套算法,规定了数据副本之间的访问优先级,前端会依优先级逐一的请求数据,只要成功获取,即中断这个过程。然后我们再将副本按优先级均匀的散落在组内机器上,如此即可实现组内负载的均衡。
 
数据迁移
 
静态映射表是非常灵活的,在不达到组数上限的情况下,可以任意的增加一组或者多组机器。当然这个过程中一些数据的路由映射发生了改变,则就涉及到了历史数据的挪腾。为了在挪腾的过程中不影响服务,保证数据依然可读可写,我们开发出了对前端透明的,基于迁移标志位,通过数据双写和异步挪数据的方式实现的安全的、可回退的数据迁移流程。
 
最小不变块
 
存储层和机械硬盘层通过冷数据链接耦合在了一起。因为两层使用了相同的映射表,那么当存储层因扩容而发生迁移时,那么冷数据链接无疑也要重新寻址,进行一轮重新定位。如果我们以单键值为粒度记录冷数据链接和进行冷数据下沉,那么在万亿键值的语境下,效率无疑是低下。因此我们设计了最小不变块的算法,通过两阶段哈希,使用中间的哈希桶聚集数据,将数据键值和冷数据存储层的机器路由隔离开来。通过该算法,我们可以实现:批量的转存冷数据、热数据存储层批量的以块 (block) 为单位记录冷数据链接、当热数据存储层发生扩容时,块 (block) 内的数据不因扩容被打散掉,而可以整体的迁移到新目标机上。
 
工程实现
 
糟糕的工程实现可以毁掉一个完美的系统设计,因此,如何在工程实现的过程中,通过技术的手段,提升系统的表现,同样值得重视。
 
高效缓存
 
内存层的设计严重依赖存储层数据版本号的高效获取,那自然是版本号请求全落在内存中就可以了。因此,针对这种情况我们为定长的版本号设计了一套极简的、轻量的、行之有效的缓存――内存容量不足以支撑版本号全缓存。
005.jpg

它的数据结构只是一个二维数组,一维用来构建 hash 链,一维用来实现 LRU 链。每次读或者写都需要通过数组内数据的挪动,来进行更新。如此一来,我们就通过千万级数目的 LRU 链群,实现了缓存整体的 LRU 淘汰。它具有定长,可共享内存搭载,进程重启不丢失、内存使用率高等优点。
 
批量操作
 
对系统服务器而言,前端访问过来的某个请求,其对应的逻辑操作都是串行的,我们自然可以梳理这个串行流程中的 CPU 消耗点进行优化。然而当主要的瓶颈被逐渐的消灭掉后,CPU 消耗点变得分散,优化效果就变得微乎其微了。因此,我们只能寻找其它突破点。

我们发现在存储引擎、一致性协议算法的实现流程中,逻辑操作步骤多,涉及到网络交互,硬盘读写等过程。因此,我们决定合并不同请求中的相同步骤,实现批量化操作,极大的优化了 CPU 消耗。

合并的代价即是耗时略有增加,我们通过快慢分离,只针对热点数据请求中的逻辑操作进行合并,去掉了耗时中的不稳定因子,减少了耗时抖动。
 
请求合并
 
既然单机的逻辑操作性能已经得到了极大的提升,那么前后端的网络交互阶段,包括接入层的打包解包、协议处理等环节,成为了资源的主要消耗点。参考批量操作的经验,我们同样使用批量化的技术来优化性能――即将后台访问过来的单条请求 (Get) 在内存层聚合成一次批量请求 (Batch Get)。
 
路由收敛
 
因为每个数据都是根据键值单独进行路由的,如果要进行请求合并,我们就必须确保同一个批量请求内的数据,都会寻址到相同的 Paxos Group 上。因此,我们必须在内存层将落到同一台存储机器上的 Get 请求聚合起来。我们首先在内存层和存储层采用了相同的路由算法,然后将内存层的组数同存储层的组数进行对齐,来完成了这一目标。

006.jpg


相关工作
 
在设计的阶段,我们充分的调研了业界的各类方案,大到系统的整体架构,小到具体的技术点。各种方案自有应用场景、各有千秋,不能单纯以好坏区别,我们同样基于自己的业务场景,谨慎的选择合适的方案,或者弃而不用。在此尽量叙述。

处理 SNS 类业务生成的数据,业界有多种的冷热分离架构可以参考。我们以 Facebook 的 Cold Storage 系统举例而言,它也是基于冷热分层的想法,设计出了服务它们照片业务数据的存储方案。不同的是它采用了软硬件结合的方法,一方面定制专门的服务器(包括硬盘、电源等)和数据中心,一方面降低冷数据的备份数、增加纠删码等手段。

然而它们的经验我们是无法彻底套用的,主要两种原因:我们可使用的机器机型是固定的,不存在自己定制硬件的条件。同时它处理的是照片这种大 value 的数据。而我们基本上是文本这种类型的小 value 数据。从前文提及的 TB 访问量角度来看,它们处理的数据是容量瓶颈的,而我们处理的是 IO 瓶颈的,可以算是不太冷的冷数据带来的挑战。所以,我们只能实现自己的冷数据管理策略。

同样,业界有诸多关于如何实现数据一致性的方案。包括我们微信自研的 Quorum 协议,它是一种 NWR 协议,采用异步同步的方式实现数据多副本。即然是异步同步,那在多副本达到最终一致,必然存在一个时间差,那么在单机出现离线的情况下,就会有一定概率导致数据的不可用。而我们追求的是在单点故障下,所有的数据都保证强可用性。

因此,我们采用了无主的去中心化的 Paxos Group 实现了这一目标,其中非租约是 PaxosStore 架构的一个创新亮点。在故障时通常系统是抖动的,会有时断时续的状况,常见的租约做法在这种场景下容易出现反复切换主机而导致长期不可用,而 PaxosStore 的非租约结构能够轻松应对,始终提供良好的服务。PaxosStore 核心代码正在整理开源当中,预计四季度会正式发布,同时该项目的底层框架也基于我们已开源的协程库 github.com/libco。
 
转自“计算机与网络安全”,作者杨平安
0
评论

技术选型最怕的是什么? 一乐 技术选型 架构 环信

beyond 发表了文章 • 2619 次浏览 • 2017-02-07 16:41 • 来自相关话题

昨天聊聊架构发布了一篇关于技术选型的文章,文章作者介绍了目前流行的技术选型方式,比如有微博驱动、技术会议驱动、嗓门驱动、领导驱动.....不少读者都表示深有体会,并在评论区贴出了自己的经历。今天再推荐一篇由环信首席架构师一乐所撰写的关于技术选型的文章(旧文),希望能帮到各位。另推荐一乐的个人微信一乐来了,id是yilecoming,欢迎关注。这也许是我上半年最大的欠账,在去普吉的飞机上突发无聊,想想还了这债吧。

去年的时候,我们使用Cassandra出了一次问题,定位加修复用了一晚上。当我把经历发出来的时候,收到了下面一段话:

“一个开源产品,连官方文档都没看完大半,然后匆匆忙忙上生产环境,出了问题团团转。若是不能掌控就先不要玩,说回这Cassandra的例子,在对它不了解的情况下,仅通过Google就能解决问题,不正说明它不难掌握有大量资料可查吗,实在不行还能翻代码。”

我现在都不知道这位神仙从哪里看到的匆匆忙忙上和团团转,当时我还是忍了,因为实在太忙,口水又没那么多。当然我思考了很多,这就是你现在看到的文章。我相信它会有一些价值,毕竟有些事情有的人你不告诉他,他永远不可能知道。比如个体认知的局限,比如口无遮拦的损失,比如做事之人才会有的思考角度。

本文讲的是技术选型。

大多数技术都存在选型问题,因为技术的发展已经让一件事情可以有多种解决方案,选型问题就自然出现。前段时间也有人说过语言选型,这里举的例子是在组件、框架、服务的范畴。其中有相通之处,各位可以自行领会。
 
选型最怕什么
 
怕失败么?那肯定的。你的服务崩溃,用户愤而投诉,客户电话打到老板那里,明天你要洗干净到办公室去一趟(笑...)。而所有对失败的无法容忍,最终都会变成一句话,为什么你要选这个型?

你总要回答这个问题,所以选型一怕随意,公鸡头母鸡头,选上哪头是哪头;二怕凭感觉,某某已经在用听起来还不错。你需要真正的思考,而且尽可能的全面。我下文会详细讲解,但这还不是最怕的。

最怕的是什么?看看本文开头引用的那句话,你体会一下。

嗯,最怕的是喷子。怕任意总结,如果再加上一些诋毁,一次选型失败足以让人心碎一万次。

失败不可怕,可怕的是没有总结,因为没有总结就没有提高。而比没有总结更可怕的是乱总结。

为了方便理解,我再帮你换个角度。你天天在河边走,一次不小心湿了鞋。如果是本文说的这种人,那肯定要说:

一条公共的河,你连旱季旺季都没搞清楚,就匆匆忙忙跑过来散步,湿了鞋还到处讲。若是脚不行就别在这玩,说回这条河,湿了鞋就能爬上来,不正说明他水不深么。

这种人实在不算少见。他说的每一句话都有一点道理,但都跟事情的本质毫无关系,每一句话又都掺加了嘲讽,来体现那无处安放的莫名优越感。而所有的这些,对于解决问题和后续提高通常毫无帮助。

想想也真遗憾,人生本是如此美好,有的人却硬生生地活成了奇葩。
 
选型需要什么
 
言归正传,我认为有三点不可或缺:分析、实验和胆量。
 
 分析
 
分析主要有定性分析和定量分析。实际操作中,前者主要针对的是模型维度的估计,用来考虑一个组件是否有可能达到它宣称的目的,后者主要用来验证,用来确认它是否在真的做到了。

比如在语言选型时,你要考虑它的范型、内存模型和并发设计;数据库选型时你要考虑存储模型、支撑量级、成本开销;开源项目要考虑它的社区发展、文档完善程度;如果是库或者中间件,还要考虑他的易用性、灵活性以及可替代性,等等。

需要说明的一点是,我个人并不觉得阅读全部源码或者文档这种事情是必须的,这不局限在OS、VM层面。不仅因为这样的事情会耗费过多精力,而且受制于代码以及文档质量,就算真正阅读完毕也未必意味着完全领会。

这些都是定性的,而定性的东西就有可能存在理解偏差。一个库可以完成工作,并不代表它在高并发压力下依然表现正常;一个语言做到了自动管理内存,并不代表他能做得很好没有副作用;一件事情设计者觉得达到了目标并不代表能够满足使用者期望。因此我们还需要量化分析,也就是一直口口相传的,用数据说话。

量化分析需要你构建或使用现成的工具和数据集,对服务进行特定场景下的分析。通过提高压力、增加容量或者针对性的测试,来验证之前的定性分析是否达到预期,并分析不同技术之间的差异和表现。
 
实验
 
量化分析可以为真正的实验做一些准备和帮助,但是实验要走的明显更远。到了这一步,意味着要在真正的业务场景下进行验证,这跟量化分析中通用性场景有所不同。

在真正的业务中采用需要很多细致和琐碎的工作,除此之外,还要构建自己的测试工具集,这需要非常扎实的业务理解能力和勤奋的工作。而所有这些,你需要在开发环境做一次,在沙箱环境做一次,然后在仿真环境再做一次。

这几步经常被简化,但经验告诉我们,如果你想做一个高可用的系统,你就不应该少走任何一步。

步子大了,容易扯到蛋。 
 
胆量
 
实验做完,剩下的就是上线,但这一步有很多人跨不过去。因为就算做了再多准备,你依然不敢说百分百保证没问题。现实情况是,80%的线上问题都是升级或者上线引起的。

你需要胆量。

这不是说要硬着头皮做,人家都是艺高才胆大。所以为了让胆子大一点,你首先需要考虑降级和开关。从最悲观的角度来重新审视整个方案,如果升级出现问题怎么办,如何才能让出现的问题影响最小化。

而只要弄完了这些,也就只要再记住一句话就行:

你行你上啊!
 
对技术服务的提醒
 
得到认可
 
刚才在胆量里没说的一点。我们经常会看到,一项新技术在公司内久久难以推行,因为业务主管百般阻挠。即使排除利益纠葛,仍然会发现一种发自心底的不信任存在。而这种不信任,又往往来源于对同事工作的不认可。

这个问题原因很多,也许没有通用的解决方案,但我说一个例子。

我们最近开始使用Codis,就是@goroutine 和几个家伙之前搞过的玩意儿。虽然他们最近已经独立开搞像Google Spanner但拥有更高级特性的TiDB(就是太牛了的意思)。由于我对他们比较熟悉和认可,所以在Codis尝试方面也多出很多底气。这种信任并非完全来自于出问题之后的直接电话支持,而是真心觉得活儿好。

反过来,这对很多服务也是一个提醒,特别是云服务。也许只要你得到合作伙伴的认可,或者至少让他们觉得,自己动手不会比你做得更好,你基本也就成功了。

对于大多数理性创业公司来讲,他们还是更愿意把精力放在自己的主要业务上,不会希望所有的服务都自己做,因为这个年代,唯快不破,创业等不起一辈子。 
 
产品意识
 
回到开始那句话,“在对它不了解的情况下,仅通过google就能解决问题,不正说明它不难掌握有大量资料可查吗,实在不行还能翻代码。” 这话有些道理,然而却存在一个问题,这个问题就是:

作为一个使用者,是否有能力解决遇到的问题,与是否有意愿去遇到并解决问题,是两回事。

你有本CPU设计手册,你可以说处理器很简单,但我只想看个电影啊?给你Linux内核的源码,你可以说内核设计不难掌握,但我只想跑个游戏啊?何况他们是否因此就变得不难了,也是值得怀疑的。

这其实反映了技术人的产品意识。

很多技术人员喜欢玩酷的东西,他们愿意去探索新的领域,把不可能的变为可能。但是很多时候,他们做出来的东西却很难使用。

有的库可以增加很多参数,参数之间却有耦合,导致你在采用的时候需要写很多设置代码,而有点库却只需要一行代码;有的服务功能众多,却需要用户学习繁杂的步骤,而有的服务却可以开箱即用;有的服务功能可以实现,却会有很多不稳定甚至崩溃的情况出现,等等。

对于实现的工程师来讲,可能最大的区别在于,你是否考虑从用户的角度审视过自己的东西。即使这个服务也许只是为其他技术人员使用的。

技术人员可以,也应该,让技术人员更幸福。

最后,聊聊架构为大家送上一个关于技术选型的小漫画。其实技术并没有错,错的也许是我们.....




  查看全部

WOE262@[SP29YD2R2}GGSSQ.png
昨天聊聊架构发布了一篇关于技术选型的文章,文章作者介绍了目前流行的技术选型方式,比如有微博驱动、技术会议驱动、嗓门驱动、领导驱动.....不少读者都表示深有体会,并在评论区贴出了自己的经历。今天再推荐一篇由环信首席架构师一乐所撰写的关于技术选型的文章(旧文),希望能帮到各位。另推荐一乐的个人微信一乐来了,id是yilecoming,欢迎关注。
这也许是我上半年最大的欠账,在去普吉的飞机上突发无聊,想想还了这债吧。

去年的时候,我们使用Cassandra出了一次问题,定位加修复用了一晚上。当我把经历发出来的时候,收到了下面一段话:

“一个开源产品,连官方文档都没看完大半,然后匆匆忙忙上生产环境,出了问题团团转。若是不能掌控就先不要玩,说回这Cassandra的例子,在对它不了解的情况下,仅通过Google就能解决问题,不正说明它不难掌握有大量资料可查吗,实在不行还能翻代码。”

我现在都不知道这位神仙从哪里看到的匆匆忙忙上和团团转,当时我还是忍了,因为实在太忙,口水又没那么多。当然我思考了很多,这就是你现在看到的文章。我相信它会有一些价值,毕竟有些事情有的人你不告诉他,他永远不可能知道。比如个体认知的局限,比如口无遮拦的损失,比如做事之人才会有的思考角度。

本文讲的是技术选型。

大多数技术都存在选型问题,因为技术的发展已经让一件事情可以有多种解决方案,选型问题就自然出现。前段时间也有人说过语言选型,这里举的例子是在组件、框架、服务的范畴。其中有相通之处,各位可以自行领会。
 
选型最怕什么
 
怕失败么?那肯定的。你的服务崩溃,用户愤而投诉,客户电话打到老板那里,明天你要洗干净到办公室去一趟(笑...)。而所有对失败的无法容忍,最终都会变成一句话,为什么你要选这个型?

你总要回答这个问题,所以选型一怕随意,公鸡头母鸡头,选上哪头是哪头;二怕凭感觉,某某已经在用听起来还不错。你需要真正的思考,而且尽可能的全面。我下文会详细讲解,但这还不是最怕的。

最怕的是什么?看看本文开头引用的那句话,你体会一下。

嗯,最怕的是喷子。怕任意总结,如果再加上一些诋毁,一次选型失败足以让人心碎一万次。

失败不可怕,可怕的是没有总结,因为没有总结就没有提高。而比没有总结更可怕的是乱总结。

为了方便理解,我再帮你换个角度。你天天在河边走,一次不小心湿了鞋。如果是本文说的这种人,那肯定要说:

一条公共的河,你连旱季旺季都没搞清楚,就匆匆忙忙跑过来散步,湿了鞋还到处讲。若是脚不行就别在这玩,说回这条河,湿了鞋就能爬上来,不正说明他水不深么。

这种人实在不算少见。他说的每一句话都有一点道理,但都跟事情的本质毫无关系,每一句话又都掺加了嘲讽,来体现那无处安放的莫名优越感。而所有的这些,对于解决问题和后续提高通常毫无帮助。

想想也真遗憾,人生本是如此美好,有的人却硬生生地活成了奇葩。
 
选型需要什么
 
言归正传,我认为有三点不可或缺:分析、实验和胆量。
 
  •  分析

 
分析主要有定性分析和定量分析。实际操作中,前者主要针对的是模型维度的估计,用来考虑一个组件是否有可能达到它宣称的目的,后者主要用来验证,用来确认它是否在真的做到了。

比如在语言选型时,你要考虑它的范型、内存模型和并发设计;数据库选型时你要考虑存储模型、支撑量级、成本开销;开源项目要考虑它的社区发展、文档完善程度;如果是库或者中间件,还要考虑他的易用性、灵活性以及可替代性,等等。

需要说明的一点是,我个人并不觉得阅读全部源码或者文档这种事情是必须的,这不局限在OS、VM层面。不仅因为这样的事情会耗费过多精力,而且受制于代码以及文档质量,就算真正阅读完毕也未必意味着完全领会。

这些都是定性的,而定性的东西就有可能存在理解偏差。一个库可以完成工作,并不代表它在高并发压力下依然表现正常;一个语言做到了自动管理内存,并不代表他能做得很好没有副作用;一件事情设计者觉得达到了目标并不代表能够满足使用者期望。因此我们还需要量化分析,也就是一直口口相传的,用数据说话。

量化分析需要你构建或使用现成的工具和数据集,对服务进行特定场景下的分析。通过提高压力、增加容量或者针对性的测试,来验证之前的定性分析是否达到预期,并分析不同技术之间的差异和表现。
 
  • 实验

 
量化分析可以为真正的实验做一些准备和帮助,但是实验要走的明显更远。到了这一步,意味着要在真正的业务场景下进行验证,这跟量化分析中通用性场景有所不同。

在真正的业务中采用需要很多细致和琐碎的工作,除此之外,还要构建自己的测试工具集,这需要非常扎实的业务理解能力和勤奋的工作。而所有这些,你需要在开发环境做一次,在沙箱环境做一次,然后在仿真环境再做一次。

这几步经常被简化,但经验告诉我们,如果你想做一个高可用的系统,你就不应该少走任何一步。

步子大了,容易扯到蛋。 
 
  • 胆量

 
实验做完,剩下的就是上线,但这一步有很多人跨不过去。因为就算做了再多准备,你依然不敢说百分百保证没问题。现实情况是,80%的线上问题都是升级或者上线引起的。

你需要胆量。

这不是说要硬着头皮做,人家都是艺高才胆大。所以为了让胆子大一点,你首先需要考虑降级和开关。从最悲观的角度来重新审视整个方案,如果升级出现问题怎么办,如何才能让出现的问题影响最小化。

而只要弄完了这些,也就只要再记住一句话就行:

你行你上啊!
 
对技术服务的提醒
 
  • 得到认可

 
刚才在胆量里没说的一点。我们经常会看到,一项新技术在公司内久久难以推行,因为业务主管百般阻挠。即使排除利益纠葛,仍然会发现一种发自心底的不信任存在。而这种不信任,又往往来源于对同事工作的不认可。

这个问题原因很多,也许没有通用的解决方案,但我说一个例子。

我们最近开始使用Codis,就是@goroutine 和几个家伙之前搞过的玩意儿。虽然他们最近已经独立开搞像Google Spanner但拥有更高级特性的TiDB(就是太牛了的意思)。由于我对他们比较熟悉和认可,所以在Codis尝试方面也多出很多底气。这种信任并非完全来自于出问题之后的直接电话支持,而是真心觉得活儿好。

反过来,这对很多服务也是一个提醒,特别是云服务。也许只要你得到合作伙伴的认可,或者至少让他们觉得,自己动手不会比你做得更好,你基本也就成功了。

对于大多数理性创业公司来讲,他们还是更愿意把精力放在自己的主要业务上,不会希望所有的服务都自己做,因为这个年代,唯快不破,创业等不起一辈子。 
 
  • 产品意识

 
回到开始那句话,“在对它不了解的情况下,仅通过google就能解决问题,不正说明它不难掌握有大量资料可查吗,实在不行还能翻代码。” 这话有些道理,然而却存在一个问题,这个问题就是:

作为一个使用者,是否有能力解决遇到的问题,与是否有意愿去遇到并解决问题,是两回事。

你有本CPU设计手册,你可以说处理器很简单,但我只想看个电影啊?给你Linux内核的源码,你可以说内核设计不难掌握,但我只想跑个游戏啊?何况他们是否因此就变得不难了,也是值得怀疑的。

这其实反映了技术人的产品意识。

很多技术人员喜欢玩酷的东西,他们愿意去探索新的领域,把不可能的变为可能。但是很多时候,他们做出来的东西却很难使用。

有的库可以增加很多参数,参数之间却有耦合,导致你在采用的时候需要写很多设置代码,而有点库却只需要一行代码;有的服务功能众多,却需要用户学习繁杂的步骤,而有的服务却可以开箱即用;有的服务功能可以实现,却会有很多不稳定甚至崩溃的情况出现,等等。

对于实现的工程师来讲,可能最大的区别在于,你是否考虑从用户的角度审视过自己的东西。即使这个服务也许只是为其他技术人员使用的。

技术人员可以,也应该,让技术人员更幸福。

最后,聊聊架构为大家送上一个关于技术选型的小漫画。其实技术并没有错,错的也许是我们.....
R[Z}P6_7OS1Y}196XXK5Y.png

 
0
评论

一乐 :煎饼果子与架构模式 架构 环信

beyond 发表了文章 • 1974 次浏览 • 2016-04-18 12:13 • 来自相关话题

编者按:本文由一乐在高可用架构群分享,转载请注明来自高可用架构「 ArchNotes 」。



一乐是我,也是梁宇鹏。现任环信首席架构师兼 IM 技术总监,负责即时通讯云平台的整体研发和管理。曾任新浪微博通讯技术专家,负责微博通讯系统的设计与研发。一直专注在即时通讯领域,熟悉 XMPP 协议和相关的开源实现(包括 Jabberd2、EJabberd、Openfire)。关注分布式系统和高性能服务,关注 Erlang、Golang 和各种浪。

​煎饼的故事
有一段时间住在花园路,最难忘的就是路边的煎饼果子。老板每天晚上出来,正好是我加班回去的时间。

一勺面糊洒在锅上,刮子转一圈,再打一个蛋,依然刮平。然后啪的一下反过来,涂上辣酱,撒上葱花。空出手来,剥一根火腿肠。最后放上薄脆,咔咔咔三铲子断成三边直的长方形,折起来正好握在手中。烫烫的,一口咬下去,蛋香、酱辣、肠鲜,加上薄脆的声音和葱花的惊喜,所有的疲劳都一扫而光。




这种幸福感让我如此迷恋,以至于会在深宅的周末,穿戴整齐跑出去,就为了吃上一个。也因为理工科的恶习,我也情不自禁地开始思考这份执迷的原因,直到最后,我发现了它的秘密。
 
作为街头小吃的杰出代表,能够经历众口的挑剔而长盛不衰的秘密是什么?
 
 所有的一切全因为其模式。
而这模式与大多数互联网服务的架构如出一辙,那就是分层架构。

分层的设计意味着,每一层都独立承担单一的职责。

这在根本上降低了制作的难度。做饼的时候专心控制火候,做酱的时候专注在味道。每层职责的单一化也让优化变得简单,因为它是自然可伸缩的。你要是想多吃点蛋就多加一个,你要多吃点肠就多加一根,完全取决于你的胃口。
 
它又是可以扩展的。你可以不要蛋,你可以加根肠,你可以不要薄脆,你可以加上辣酱。而且每一层又是可定制的。葱花可以少一点,辣酱可以多一点,肠可以要两根,鸡蛋可以加三个。

你也可以把面饼换成面包,把鸡蛋换成煎蛋,把辣酱换成甜酱。你已经知道这是什么了吧?是的,你好,这里是赛百味,请问你要什么口味的三明治?

煎饼果子和三明治,其实本质上是相通的。而加一个蛋更香,也不是因为对蛋的追求,在根本上是因为煎饼果子模式的强大。

因为这种模式,一千个人可以有一千种煎饼果子。
而有了对模式的理解,对小吃的评估也就变得更加容易。比如肉夹馍只有馍和肉,二维切换单调不可长久;比如烤冷面,干脆就是满嘴的热烈混在一起,没有煎饼这样的表现层,整个面都散发着原始的不讲究。

这种对比上的简化,也让我们有了新的选择,保存宝贵的精力,并且可以随时放弃对细节的追究。




就像在我们谈论女人时,

(抱歉博主是男人)

我们在意胸、

在意腿、

在意风情、

在意温柔,

因为女人是有区别的。

当我们欣赏电影的时候,

我们在意男人、

在意女人、

在意老人、

在意孩子,

因为角色是有区别的。

当我们走在路上的时候,

我们在意行人、

在意车辆、

在意商店、

在意餐厅,

因为物体是有区别的。
我们在设计和优化系统的时候,其中的每个服务都是自行运转,做着自己份内的事,但是在不同的维度里,作用却变得不尽相同。

这也是我们讲优化要分层次和级别,架构、算法、库和 OS,而讲架构的时候,我们首先讲的是整体的模式,然后是具体的权衡,实现的细节则是最不重要的。

架构的模式
谈起这个,是因为 Mark Richards 写了一本架构模式的书《Software Architecture Pattens》。

书中总结对比了五种模式的优缺点,包括了 Layered、Event-Driven、Microkernel、Microservices、Space-Based。

书写得简单精致,推荐大家去阅读,地址见文末。

还有一种模式,因为在越来越多的系统中用到,是书中没有的(与 Space-Based 有所区别),但我觉得也有必要专门介绍下。我们开始在群发系统中实现,后来的抢购、红包和火车票的场景中也屡屡看到它的身影。


2013 年的时候,我们在微博做粉丝服务平台,一个类似微信公众号的群发系统。然而比后者更困难的是,当时在产品设计上并没有像微信一样新建用户体系,而是直接基于微博的粉丝关系,这就意味着一篇文章要能能在很短时间内支持亿级的用户推送。这个数量级的订阅用户,即使看今天的微信公众号依然是难以想象的。
当时有一套老的群发系统,都是基于 MySQL 的收件箱设计,在更换了 SSD 硬盘,又批量化数据库操作之后,整体写入性能依然只在每秒几万的级别,这就意味着一亿用户只能在 17 分钟内发完,我们意识到这套系统需要进行重新设计。

最终我们我们使用了一种新的架构方式,达到了每秒百万级别的速度,而且还可以更高。这种模式就是单元化架构。

下文介绍我参照了架构模式的说明方式,希望能够让大家有个对比,喜欢你可一定要说好!

单元化架构
如前所述,我们选择单元化的一个重要目的是为了性能,为了极高的性能。这比起一般的分层架构来讲,会获得更经济的结果,但也因此,牺牲了分层架构的一些特性,因为它的容量取决于单元的大小(关于单元等名词介绍,我会在下文介绍)。

虽然它支持按照单元扩容,但在单元内基本上每层的性能都是固定的。这更适合容量可预期的场景,比如大多数已经趋于稳定的业务。像前面的粉丝服务平台,虽然他下发消息量级巨大,但是在整体层面,使用平台的用户由于是 VIP 用户,其规模基本在在数百万级别,而粉丝量级也不太可能过亿。

重要的是,基于当时的业务数据,我们已经知道平均粉丝数在什么量级。而业务数据是架构选型的重要依据。商品秒杀、火车抢票等等都是一样。
 
当然也有例外。因为单元化架构作为一种思想,它不会局限在一台机器,一个机架,它也适用一个机房。当它的层次变大时,单元内自然就可以有变化的空间。每一层服务都可以分开伸缩。而到了这个层面,它的追求可能就完全不一样了。像阿里的双十一服务改造,会为了流量的分离,像 QQ 的聊天,会为了接入的速度。它们的基本思想是一致的。

至于单元化架构和煎饼果子的关系,我会在文后回答。




核心概念 Key Concepts
分区(Shard)是整体数据集的一个子集。如果你用尾号来划分用户,那么相同尾号的用户可以认为是同一分区。

单元(Cell)是满足某个分区所有业务操作的自包含的安装。我们从并行计算领域里借鉴了这个思想,也就是计算机体系结构里的 Celluar Architecture,在那里一个 Cell 是一个包含了线程部件、内存以及通讯组件的计算节点。 https://en.m.wikipedia.org/wik ... cture

单元化(Cellize)这是我的自造词,描述一个服务改造成单元架构的过程。

模式描述 Patten Description
单元架构最重要的概念,就是单元和单元的自治。

你可以将其想象成细胞,如之前所述,每个细胞都是自成一体,功能明确。你也可以将其想象成小隔间,就像你去了一个按摩院,每个隔间里都有技师和所有设备。我没有用前面那个名字,因为其有太强的生物学含义,也没有用后者,因为其有太多的服务性暗示。但是如果你有足够的想象力,其实什么名字都可以的。

说到单元的自治,即单元的自我协调和之间的隔离。单元既然做到了自包含,那么其中的所有组件,不管是否在物理上分离成了独立的服务,都是在一个单元内互相支持的,也就是跟其他单元内的同类和非同类组件都不会有任何交流。这也是跟基于空间的架构的重要区别,后者的处理单元之间还是会互相通信并同步信息。

这里的挑战就在于分区的算法。一个单元内的组件会很多,如果业务复杂,涉及到的数据也会很多,为了隔离,每一个组件都要能按照同样的算法进行分区。

本质上每个单元都是相似的,单元之间的区别或者取决于请求,或者取决于数据。而且越到大的层面,区分度越低,用户甚至是可以在不同单元间漫游的。

模式动力学 Patten Dynamics
单元架构的最典型目的,还是为了极高的性能,为了获得经济的高速度。这里一方面,是因为我们发现其他架构实际上是浪费了很多资源,每一层服务都运行在单独的操作系统上,而且都要通过局域网或者城域网中转。

与此同时,传统的互联网服务还是希望用一堆计算能力普通的节点来服务大量用户,而随着摩尔定律的推进,单机性能越来越高,网络通讯的成本随之变得耗费显著。这使得我们有机会也有动力在垂直方向进行扩展。

当你把更多的组件放在同一个地方的时候,你也在物理上获得了计算本地化的优势。这是我们获得性能提升的根本原因。

服务分成了很多单元,但总要跟外界通讯,这个事情是交给协调者 Coordinator 的。你可以在内部增加存储、缓存,增加队列和处理机,这些所有不交互的组件,理论上都不是外部资源可以访问的。

前面我们提到,单元化过程也是分区算法的应用过程。而这个分区算法放在哪里就是个问题。

我们可以封装运行库交给客户端,也可以做个代理层,内置算法。也有一些服务因为业务需要,请求需要复制到每个单元去。这就是典型的 Scatter-Gatter 模型,那么你还可能需要一个作业管理系统。这些都是可选择的使用方式。

模式分析 Patten Analysis
总体敏捷度低,易部署性低,可测试性高,性能高,伸缩性高,易开发性低。

基于篇幅原因,不再详述每一个方面,相信大家都能自行分析。唯一需要强调的是运维要求比较高。

单元化之后,所有的服务放在一起,在请求失败的情况下需要快速定位某个单元,这跟分层排除的思路是不一样的。如果运维团队不够高效,面对这样集群数量的暴涨(每个单元的服务数量相当于原来一个集群的服务数量),有可能是会被大量的工作压垮;如果运维团队分离比较明显,每种组件都是专门的团队来维护(这是我们在微博遇到的),那就会有排异反应的风险,因为每一个团队都有自己的权限和服务管理习惯,这里需要相当的协调工作来防止相互干扰。
后记

前面留的一个问题,煎饼果子跟单元化架构的关系。答案说起来很简单,你问问煎饼摊就知道了。

煎饼是分层的,煎饼摊是单元的。消息发送服务是单元的,但是索引维护是分层的。看模式要确定系统的范畴,从不同角度看,同样的东西是有不同意义的。这也是架构师要做的思考。

其实 IT 系统千百万,模式肯定不会止于这几种。但有了基础的模式,了解它们之间的相似和区别,对于我们设计自己的系统,思考其中的权衡都是有帮助的。
Q & A

1. 单元化设计与 Docker 的容器化思路是否相通?又有何差异呢?

一乐:应该是关注的点不一样,但不冲突。Docker 一般是在微服务架构下会使用的措施,但并不意味着不能用在其他架构上。一个单元内的各种组件,使用什么样的技术,都是新的选择。用 Docker 不错。

2. 对于分布式服务,单元化架构可能会带来数据一致性问题,这个一般如何解决?

一乐:可能我没有理解你场景,单元化一般不会带来一致性问题。因为 Sharding 之后,一块分区数据相当于完全属于一个单元,其他单元是被隔离访问的。


3. 单元化架构最小情况是单台机部署整体服务,资源方面如何规划?

一乐:这方面就要计算了,也就是进行容量规划,相信大家在这方面都很熟悉。一个需要注意的点是,单元化的架构应用在可预期的总体容量上时会省很多事。鉴于分区算法的固定,扩容方面,其实可以通过预先规划,在单机上再进行多单元混部的方式。

4. 单元与 app cluster(总服务器)之间是怎么进行关联的,是通过注册服务还是按照 hash 分派的,如果是 hash 分派,那么挂了怎么接回的,如果是注册服务,是怎么对应分派服务呢?

一乐:简单做就是 hash 分派,高级点就是注册服务,可以直接参照成熟的 Sharding 算法。任务只要到了单元内,就是单元自己的事了。如果你的 Job 有阶段性,可能要考虑 Job 状态记录以及请求处理的幂等性

5. 你觉得单元化架构的问题是什么?如果让你重新设计你会做哪些改进?

一乐:这个问题太聪明了,谢谢!单元化架构的问题,如之前所说,有一个扩容难题,有一个运维难题,有一个单点问题。扩容问题刚才说了,在三年前我们还没有 Docker 的时候,我们的服务隔离难度很大,现在已经今非昔比。一刀(Docker)在手,天下我有!单元的单点问题,你得考虑单元级别的主从同步,这方面常见的互联网技术就行。

6. 分布式架构经常讲究服务器无状态,这样可以单台服务器异常对整体服务无影响。但单元化意味着服务是有状态,如何保障高可用?

一乐:无状态只能是业务层,涉及到数据的不会无状态,因为数据就是状态的记录。保障高可用嘛,前面说了,先把主从做了吧。

7. 单元细胞内依然采用分层架构设计还是 ALL IN ONE 即可?

一乐:在讲单元化的时候,其实不要求单元内的组织模式,所以回答是都行。

8. “每秒百万级的推送” 除了采用这种单元化的架构模式使之成为可能对于基础的中间件如 队列 db 等的架构如何规划的?还要额外考虑哪些技术点或问题?

一乐:队列主要用来防峰,在高速服务里,如果再想扩容,肯定先走批量的路子。db 的规划其实是重点,单元化架构实际上算是以数据为中心的一种模式。额外的考虑其实跟之前都很像,不过要做一些特殊的处理,比如冷热数据的分离。
参考阅读

一个单元化架构的例子 http://t.cn/RqM5Ns0

Software Architecture Patterns http://www.oreilly.com/program ... s.csp

校长:技术成长四个阶段需要的架构知识
 
支撑微博千亿调用的轻量级RPC框架:Motan

Upsync:微博开源基于Nginx容器动态流量管理方案

小编:一乐最近也开了公众号,内容非常有特色,将复杂的道理说得如煎饼这么通透,所以别忘了识别二维码关注,错过这次小编琢磨最短都要再等一年。




本文策划庆丰,编辑王杰,想讨论更多架构设计,请关注公众号获取进群机会。转载请注明来自高可用架构「ArchNotes」微信公众号及包含以下二维码。 查看全部

640.webp_.jpg


编者按:本文由一乐在高可用架构群分享,转载请注明来自高可用架构「 ArchNotes 」。

640.webp_(1)_.jpg
一乐是我,也是梁宇鹏。现任环信首席架构师兼 IM 技术总监,负责即时通讯云平台的整体研发和管理。曾任新浪微博通讯技术专家,负责微博通讯系统的设计与研发。一直专注在即时通讯领域,熟悉 XMPP 协议和相关的开源实现(包括 Jabberd2、EJabberd、Openfire)。关注分布式系统和高性能服务,关注 Erlang、Golang 和各种浪。



​煎饼的故事

有一段时间住在花园路,最难忘的就是路边的煎饼果子。老板每天晚上出来,正好是我加班回去的时间。

一勺面糊洒在锅上,刮子转一圈,再打一个蛋,依然刮平。然后啪的一下反过来,涂上辣酱,撒上葱花。空出手来,剥一根火腿肠。最后放上薄脆,咔咔咔三铲子断成三边直的长方形,折起来正好握在手中。烫烫的,一口咬下去,蛋香、酱辣、肠鲜,加上薄脆的声音和葱花的惊喜,所有的疲劳都一扫而光。


640.webp_(2)_.jpg


这种幸福感让我如此迷恋,以至于会在深宅的周末,穿戴整齐跑出去,就为了吃上一个。也因为理工科的恶习,我也情不自禁地开始思考这份执迷的原因,直到最后,我发现了它的秘密。
 
作为街头小吃的杰出代表,能够经历众口的挑剔而长盛不衰的秘密是什么?


 
 所有的一切全因为其模式。

而这模式与大多数互联网服务的架构如出一辙,那就是分层架构。

分层的设计意味着,每一层都独立承担单一的职责。

这在根本上降低了制作的难度。做饼的时候专心控制火候,做酱的时候专注在味道。每层职责的单一化也让优化变得简单,因为它是自然可伸缩的。你要是想多吃点蛋就多加一个,你要多吃点肠就多加一根,完全取决于你的胃口。
 
它又是可以扩展的。你可以不要蛋,你可以加根肠,你可以不要薄脆,你可以加上辣酱。而且每一层又是可定制的。葱花可以少一点,辣酱可以多一点,肠可以要两根,鸡蛋可以加三个。

你也可以把面饼换成面包,把鸡蛋换成煎蛋,把辣酱换成甜酱。你已经知道这是什么了吧?是的,你好,这里是赛百味,请问你要什么口味的三明治?

煎饼果子和三明治,其实本质上是相通的。而加一个蛋更香,也不是因为对蛋的追求,在根本上是因为煎饼果子模式的强大。



因为这种模式,一千个人可以有一千种煎饼果子。

而有了对模式的理解,对小吃的评估也就变得更加容易。比如肉夹馍只有馍和肉,二维切换单调不可长久;比如烤冷面,干脆就是满嘴的热烈混在一起,没有煎饼这样的表现层,整个面都散发着原始的不讲究。

这种对比上的简化,也让我们有了新的选择,保存宝贵的精力,并且可以随时放弃对细节的追究。


640.webp_(1)_.jpg

就像在我们谈论女人时,

(抱歉博主是男人)

我们在意胸、

在意腿、

在意风情、

在意温柔,

因为女人是有区别的。

当我们欣赏电影的时候,

我们在意男人、

在意女人、

在意老人、

在意孩子,

因为角色是有区别的。

当我们走在路上的时候,

我们在意行人、

在意车辆、

在意商店、

在意餐厅,

因为物体是有区别的。


我们在设计和优化系统的时候,其中的每个服务都是自行运转,做着自己份内的事,但是在不同的维度里,作用却变得不尽相同。

这也是我们讲优化要分层次和级别,架构、算法、库和 OS,而讲架构的时候,我们首先讲的是整体的模式,然后是具体的权衡,实现的细节则是最不重要的。



架构的模式

谈起这个,是因为 Mark Richards 写了一本架构模式的书《Software Architecture Pattens》。

书中总结对比了五种模式的优缺点,包括了 Layered、Event-Driven、Microkernel、Microservices、Space-Based。

书写得简单精致,推荐大家去阅读,地址见文末。

还有一种模式,因为在越来越多的系统中用到,是书中没有的(与 Space-Based 有所区别),但我觉得也有必要专门介绍下。我们开始在群发系统中实现,后来的抢购、红包和火车票的场景中也屡屡看到它的身影。


2013 年的时候,我们在微博做粉丝服务平台,一个类似微信公众号的群发系统。然而比后者更困难的是,当时在产品设计上并没有像微信一样新建用户体系,而是直接基于微博的粉丝关系,这就意味着一篇文章要能能在很短时间内支持亿级的用户推送。这个数量级的订阅用户,即使看今天的微信公众号依然是难以想象的。
当时有一套老的群发系统,都是基于 MySQL 的收件箱设计,在更换了 SSD 硬盘,又批量化数据库操作之后,整体写入性能依然只在每秒几万的级别,这就意味着一亿用户只能在 17 分钟内发完,我们意识到这套系统需要进行重新设计。

最终我们我们使用了一种新的架构方式,达到了每秒百万级别的速度,而且还可以更高。这种模式就是单元化架构。

下文介绍我参照了架构模式的说明方式,希望能够让大家有个对比,喜欢你可一定要说好!



单元化架构

如前所述,我们选择单元化的一个重要目的是为了性能,为了极高的性能。这比起一般的分层架构来讲,会获得更经济的结果,但也因此,牺牲了分层架构的一些特性,因为它的容量取决于单元的大小(关于单元等名词介绍,我会在下文介绍)。

虽然它支持按照单元扩容,但在单元内基本上每层的性能都是固定的。这更适合容量可预期的场景,比如大多数已经趋于稳定的业务。像前面的粉丝服务平台,虽然他下发消息量级巨大,但是在整体层面,使用平台的用户由于是 VIP 用户,其规模基本在在数百万级别,而粉丝量级也不太可能过亿。

重要的是,基于当时的业务数据,我们已经知道平均粉丝数在什么量级。而业务数据是架构选型的重要依据。商品秒杀、火车抢票等等都是一样。
 
当然也有例外。因为单元化架构作为一种思想,它不会局限在一台机器,一个机架,它也适用一个机房。当它的层次变大时,单元内自然就可以有变化的空间。每一层服务都可以分开伸缩。而到了这个层面,它的追求可能就完全不一样了。像阿里的双十一服务改造,会为了流量的分离,像 QQ 的聊天,会为了接入的速度。它们的基本思想是一致的。

至于单元化架构和煎饼果子的关系,我会在文后回答。


640.webp_(3)_.jpg


核心概念 Key Concepts

分区(Shard)是整体数据集的一个子集。如果你用尾号来划分用户,那么相同尾号的用户可以认为是同一分区。

单元(Cell)是满足某个分区所有业务操作的自包含的安装。我们从并行计算领域里借鉴了这个思想,也就是计算机体系结构里的 Celluar Architecture,在那里一个 Cell 是一个包含了线程部件、内存以及通讯组件的计算节点。 https://en.m.wikipedia.org/wik ... cture

单元化(Cellize)这是我的自造词,描述一个服务改造成单元架构的过程。



模式描述 Patten Description

单元架构最重要的概念,就是单元和单元的自治

你可以将其想象成细胞,如之前所述,每个细胞都是自成一体,功能明确。你也可以将其想象成小隔间,就像你去了一个按摩院,每个隔间里都有技师和所有设备。我没有用前面那个名字,因为其有太强的生物学含义,也没有用后者,因为其有太多的服务性暗示。但是如果你有足够的想象力,其实什么名字都可以的。

说到单元的自治,即单元的自我协调和之间的隔离。单元既然做到了自包含,那么其中的所有组件,不管是否在物理上分离成了独立的服务,都是在一个单元内互相支持的,也就是跟其他单元内的同类和非同类组件都不会有任何交流。这也是跟基于空间的架构的重要区别,后者的处理单元之间还是会互相通信并同步信息。

这里的挑战就在于分区的算法。一个单元内的组件会很多,如果业务复杂,涉及到的数据也会很多,为了隔离,每一个组件都要能按照同样的算法进行分区。

本质上每个单元都是相似的,单元之间的区别或者取决于请求,或者取决于数据。而且越到大的层面,区分度越低,用户甚至是可以在不同单元间漫游的。



模式动力学 Patten Dynamics

单元架构的最典型目的,还是为了极高的性能,为了获得经济的高速度。这里一方面,是因为我们发现其他架构实际上是浪费了很多资源,每一层服务都运行在单独的操作系统上,而且都要通过局域网或者城域网中转。

与此同时,传统的互联网服务还是希望用一堆计算能力普通的节点来服务大量用户,而随着摩尔定律的推进,单机性能越来越高,网络通讯的成本随之变得耗费显著。这使得我们有机会也有动力在垂直方向进行扩展。

当你把更多的组件放在同一个地方的时候,你也在物理上获得了计算本地化的优势。这是我们获得性能提升的根本原因。

服务分成了很多单元,但总要跟外界通讯,这个事情是交给协调者 Coordinator 的。你可以在内部增加存储、缓存,增加队列和处理机,这些所有不交互的组件,理论上都不是外部资源可以访问的。

前面我们提到,单元化过程也是分区算法的应用过程。而这个分区算法放在哪里就是个问题。

我们可以封装运行库交给客户端,也可以做个代理层,内置算法。也有一些服务因为业务需要,请求需要复制到每个单元去。这就是典型的 Scatter-Gatter 模型,那么你还可能需要一个作业管理系统。这些都是可选择的使用方式。



模式分析 Patten Analysis

总体敏捷度低,易部署性低,可测试性高,性能高,伸缩性高,易开发性低。

基于篇幅原因,不再详述每一个方面,相信大家都能自行分析。唯一需要强调的是运维要求比较高。

单元化之后,所有的服务放在一起,在请求失败的情况下需要快速定位某个单元,这跟分层排除的思路是不一样的。如果运维团队不够高效,面对这样集群数量的暴涨(每个单元的服务数量相当于原来一个集群的服务数量),有可能是会被大量的工作压垮;如果运维团队分离比较明显,每种组件都是专门的团队来维护(这是我们在微博遇到的),那就会有排异反应的风险,因为每一个团队都有自己的权限和服务管理习惯,这里需要相当的协调工作来防止相互干扰。


后记

前面留的一个问题,煎饼果子跟单元化架构的关系。答案说起来很简单,你问问煎饼摊就知道了。

煎饼是分层的,煎饼摊是单元的。消息发送服务是单元的,但是索引维护是分层的。看模式要确定系统的范畴,从不同角度看,同样的东西是有不同意义的。这也是架构师要做的思考。

其实 IT 系统千百万,模式肯定不会止于这几种。但有了基础的模式,了解它们之间的相似和区别,对于我们设计自己的系统,思考其中的权衡都是有帮助的。


Q & A

1. 单元化设计与 Docker 的容器化思路是否相通?又有何差异呢?

一乐:应该是关注的点不一样,但不冲突。Docker 一般是在微服务架构下会使用的措施,但并不意味着不能用在其他架构上。一个单元内的各种组件,使用什么样的技术,都是新的选择。用 Docker 不错。

2. 对于分布式服务,单元化架构可能会带来数据一致性问题,这个一般如何解决?

一乐:可能我没有理解你场景,单元化一般不会带来一致性问题。因为 Sharding 之后,一块分区数据相当于完全属于一个单元,其他单元是被隔离访问的。


3. 单元化架构最小情况是单台机部署整体服务,资源方面如何规划?

一乐:这方面就要计算了,也就是进行容量规划,相信大家在这方面都很熟悉。一个需要注意的点是,单元化的架构应用在可预期的总体容量上时会省很多事。鉴于分区算法的固定,扩容方面,其实可以通过预先规划,在单机上再进行多单元混部的方式。

4. 单元与 app cluster(总服务器)之间是怎么进行关联的,是通过注册服务还是按照 hash 分派的,如果是 hash 分派,那么挂了怎么接回的,如果是注册服务,是怎么对应分派服务呢?

一乐:简单做就是 hash 分派,高级点就是注册服务,可以直接参照成熟的 Sharding 算法。任务只要到了单元内,就是单元自己的事了。如果你的 Job 有阶段性,可能要考虑 Job 状态记录以及请求处理的幂等性

5. 你觉得单元化架构的问题是什么?如果让你重新设计你会做哪些改进?

一乐:这个问题太聪明了,谢谢!单元化架构的问题,如之前所说,有一个扩容难题,有一个运维难题,有一个单点问题。扩容问题刚才说了,在三年前我们还没有 Docker 的时候,我们的服务隔离难度很大,现在已经今非昔比。一刀(Docker)在手,天下我有!单元的单点问题,你得考虑单元级别的主从同步,这方面常见的互联网技术就行。

6. 分布式架构经常讲究服务器无状态,这样可以单台服务器异常对整体服务无影响。但单元化意味着服务是有状态,如何保障高可用?

一乐:无状态只能是业务层,涉及到数据的不会无状态,因为数据就是状态的记录。保障高可用嘛,前面说了,先把主从做了吧。

7. 单元细胞内依然采用分层架构设计还是 ALL IN ONE 即可?

一乐:在讲单元化的时候,其实不要求单元内的组织模式,所以回答是都行。

8. “每秒百万级的推送” 除了采用这种单元化的架构模式使之成为可能对于基础的中间件如 队列 db 等的架构如何规划的?还要额外考虑哪些技术点或问题?

一乐:队列主要用来防峰,在高速服务里,如果再想扩容,肯定先走批量的路子。db 的规划其实是重点,单元化架构实际上算是以数据为中心的一种模式。额外的考虑其实跟之前都很像,不过要做一些特殊的处理,比如冷热数据的分离。


参考阅读

一个单元化架构的例子 http://t.cn/RqM5Ns0

Software Architecture Patterns http://www.oreilly.com/program ... s.csp

校长:技术成长四个阶段需要的架构知识
 
支撑微博千亿调用的轻量级RPC框架:Motan

Upsync:微博开源基于Nginx容器动态流量管理方案



小编:一乐最近也开了公众号,内容非常有特色,将复杂的道理说得如煎饼这么通透,所以别忘了识别二维码关注,错过这次小编琢磨最短都要再等一年。

640.webp_(4)_.jpg


本文策划庆丰,编辑王杰,想讨论更多架构设计,请关注公众号获取进群机会。转载请注明来自高可用架构「ArchNotes」微信公众号及包含以下二维码。

640.webp_(5)_.jpg


0
评论

环信首席架构师:一个单元化架构的例子 架构

beyond 发表了文章 • 1330 次浏览 • 2016-04-11 14:14 • 来自相关话题

微博粉丝服务平台在单元化架构方面的实践已经在QCon讲过,这次重又写起文章,我想传播知识已经不那么重要(单元化架构不是创新,稍后会详细介绍),更重要的是还是希望能够借此引起诸位的思考,能够在架构层面多投入精力思考和尝试。
 
为什么要有架构实践?

很多人喜欢的是细节,因为有句名言叫魔鬼在细节里,于是都去细节里寻找魔鬼。但是打败了魔鬼就能看到天使么?未必。细节其实是最容易掌握的部分,细节之外还有很多。就像有了水泥和沙子,你能够做出混凝土,但是离建成高楼大厦还有很长的路要走一样,你要学着去设计架构。

但是事情并没有完,就像没有唯一的真理一样,架构也并不是只有一种。你不可能一朝学会,从此天下无敌。如果要赈灾,你需要的是帐篷,如果要重建,你需要的是瓦房。不同的住所需要的是不同的架构。
 
不同的服务也需要不同的架构设计,这也就是我们需要架构实践的重要原因。在这之后的原因,是我们做任何服务,都要考虑服务的性能和成本。

但优化有很多方式,为什么是架构呢?诚然,从硬件到操作系统,从共享库到应用软件,从算法到架构,每一层都可以优化,但每一层所做的工作量和收益也都是不同的。架构可能是需要投入最多精力的,但在很多时候却也是很少的可以提供超过数量级的提升方式。

所以,思维方式的转变才是你最应该在意的部分,单元化只是一个例子,而粉丝服务平台只是这个例子的例子,而已。

言归正传,接下来本文将从三个问题来介绍这次实践,单元化是什么,为什么要用以及我们如何做到的。

 
1. 单元化是什么

单元化架构是从并行计算领域发展而来。在分布式服务设计领域,一个单元(Cell)就是满足某个分区所有业务操作的自包含的安装。而一个分区(Shard),则是整体数据集的一个子集,如果你用尾号来划分用户,那同样尾号的那部分用户就可以认为是一个分区。单元化就是将一个服务设计改造让其符合单元特征的过程。




图 1 :洋葱细胞的显微镜截图,单元化要达到的目的就是让每个单元像细胞一样独立工作
在传统的服务化架构下(如下图),服务是分层的,每一层使用不同的分区算法,每一层都有不同数量的节点,上层节点随机选择下层节点。当然这个随机是比较而言的。




图 2 :传统的服务化架构,为伸缩性设计,上层节点随机选择下层节点
与其不同的是,在单元化架构下,服务虽然分层划分,但每个单元自成一体。按照层次来讲的话,所有层使用相同的分区算法,每一层都有相同数量的节点,上层节点也会访问指定的下层节点。因为他们已经在一起。




图 3 :单元化架构,为性能和隔离性而设计,上层节点访问指定下层节点
 
 2. 为什么要用单元化

在性能追求和成本限制的情况下,我们需要找到一种合适的方法来满足服务需求。在传统的分布式服务设计,我们考虑的更多是每个服务的可伸缩性,当各个服务独立设计时你就要在每一层进行伸缩性的考虑。这是服务化设计(SOA)流行的原因,我们需要每个服务能够单独水平扩展。
但是在摩尔定律下,随着硬件的不断升级,计算机硬件能力已经越来越强,CPU越来越快,内存越来越大,网络越来越宽。这让我们看到了在单台机器上垂直扩展的机会。尤其是当你遇到一个性能要求和容量增长可以预期的业务,单元化给我们提供另外的机会,让我们可以有效降低资源的使用,提供更高性能的服务。

总体而言,更高性能更低成本是我们的主要目标,而经过单元化改造,我们得以用更少(约二分之一)的机器,获得了比原来更高(接近百倍)的性能。性能的提升很大部分原因在于服务的本地化,而服务的集成部署又进一步降低了资源的使用。

当然除了性能收益,如果你做到了,你会发现还有很多收益,比如更好的隔离性,包括请求隔离和资源隔离,比如更友好的升级,产品可以灰度发布等。单元化改造后对高峰的应对以及扩容方式等问题,各位可以参考#微博春节技术保障系列#中的单元化架构文章,也不在此一一赘述。


3. 我们如何做到

此次单元化改造基于微博现有的业务,因此这里也先行介绍一下。粉丝服务平台是微博的内容推送系统(代号Castalia),可为V用户提供向其粉丝推送高质量内容的高速通道(单元化之后已到达百万条每秒)。整个服务涉及用户筛选、发送计费、屏蔽检查、限流控制和消息群发等多个子服务。由于改造思想相通,这里以用户筛选和消息群发两个服务为例,下面两图分别为商业群发在服务化思想和单元化思想下不同的架构。




图 4: 服务化思想下的商业群发架构设计(旧版)




图 5 :商业群发在单元化思想下的架构设计(新版)
对于筛选服务,在服务化架构里,需要去粉丝服务获取粉丝关系,然后去特征服务进行用户特征筛选,最后将筛选结果传输到群发服务器上;而在单元化架构里,粉丝关系直接就在本地文件中,用户特征服务也在本地,最后的筛选结果再不需要传输。服务本地化(粉丝关系和用户特征存储)减去了网络开销,降低了服务延时,还同时提高了访问速度和稳定性,而筛选结果本地存储又进一步节省了带宽并降低了延迟。以百万粉丝为例,每次网络操作的减少节省带宽8M左右,延时也从400ms降为0。

群发服务同样如此。由于在服务化架构里,我们使用MySQL和Memcache的方案,由于关系数据库的写入性能问题,中间还有队列以及相应的队列处理机,所有四个模块都有单独的机器提供服务,而在单元化架构里,四合一之后,只需要一套机器。当然机器的配置可能会有所提升,但真正计算之后你就会发现其实影响微乎其微。原因除了前面介绍的硬件增长空间外,上架机器的基本配置变高也是一个原因。而且,在单元化方案里,当我们把缓存部署在本地之后,其性能还有了额外的20%提升。


一些业务特有问题

不过群发这个场景,我们也遇到了一些特定的问题,一是分区问题,一是作业管理。这里也与各位分享下我们的解决方法。

分区问题分区问题其实是每个服务都会遇到的,但单元化后的挑战在于让所有服务都适配同一分区算法,在我们的场景下,我们按照接收者进行了分区,即从底层往上,每一层都来适配此分区算法。这里有特例的是用户特征和屏蔽服务,由于总体容量都很小,我们就没有对数据进行分区,所有单元内都是同一套全量数据,都是一个外部全量库的从库。不过由于本单元内的上层服务的关系,只有属于本分区的用户数据被访问到。所以,适配同一分区算法在某种程度上讲,可以兼容即可。

作业管理按照前面的分区方式,将群发服务的整体架构变成了一个类似Scatter-Gather+CQRS的方案,因为Gather不是一个请求处理的必须要素。也就是说,一个群发请求会被扩散到所有单元中,每个单元都要针对自己分区内的用户处理这个群发请求。广播方式的引入,使得我们首先需要在前端机进行分单元作业的处理监控,我们在此增加了持久化队列来解决。同时,由于单元内每个服务也都是单独维护的,作业可能在任何时间中断,因此每个作业在单元内的状态也都是有记录的,以此来达到作业的可重入和幂等性,也就可以保证每个作业都可以在任何时间重做,但不会重复执行。

除此之外,我们还对服务器进行了更为精细的控制,使用CPU绑定提高多服务集成部署时的整体效率,使用多硬盘设计保证每个服务的IO性能,通过主从单元的读写分离来提高整体服务等等。

后记

我平时不善文章,现在要成文发表,还是有一点紧张的。不过想到或许可以抛砖引玉,有机会向各位大牛学习,或者跟各位同学一起交流,内心又有些许期待。关于微博或者其他任何网站的设计,欢迎大家一起探讨,随时在微博恭候。





  查看全部
微博粉丝服务平台在单元化架构方面的实践已经在QCon讲过,这次重又写起文章,我想传播知识已经不那么重要(单元化架构不是创新,稍后会详细介绍),更重要的是还是希望能够借此引起诸位的思考,能够在架构层面多投入精力思考和尝试。
 
为什么要有架构实践?

很多人喜欢的是细节,因为有句名言叫魔鬼在细节里,于是都去细节里寻找魔鬼。但是打败了魔鬼就能看到天使么?未必。细节其实是最容易掌握的部分,细节之外还有很多。就像有了水泥和沙子,你能够做出混凝土,但是离建成高楼大厦还有很长的路要走一样,你要学着去设计架构。

但是事情并没有完,就像没有唯一的真理一样,架构也并不是只有一种。你不可能一朝学会,从此天下无敌。如果要赈灾,你需要的是帐篷,如果要重建,你需要的是瓦房。不同的住所需要的是不同的架构。
 
不同的服务也需要不同的架构设计,这也就是我们需要架构实践的重要原因。在这之后的原因,是我们做任何服务,都要考虑服务的性能和成本。

但优化有很多方式,为什么是架构呢?诚然,从硬件到操作系统,从共享库到应用软件,从算法到架构,每一层都可以优化,但每一层所做的工作量和收益也都是不同的。架构可能是需要投入最多精力的,但在很多时候却也是很少的可以提供超过数量级的提升方式。

所以,思维方式的转变才是你最应该在意的部分,单元化只是一个例子,而粉丝服务平台只是这个例子的例子,而已。

言归正传,接下来本文将从三个问题来介绍这次实践,单元化是什么,为什么要用以及我们如何做到的。

 
1. 单元化是什么

单元化架构是从并行计算领域发展而来。在分布式服务设计领域,一个单元(Cell)就是满足某个分区所有业务操作的自包含的安装。而一个分区(Shard),则是整体数据集的一个子集,如果你用尾号来划分用户,那同样尾号的那部分用户就可以认为是一个分区。单元化就是将一个服务设计改造让其符合单元特征的过程。

640.webp_.jpg

图 1 :洋葱细胞的显微镜截图,单元化要达到的目的就是让每个单元像细胞一样独立工作


在传统的服务化架构下(如下图),服务是分层的,每一层使用不同的分区算法,每一层都有不同数量的节点,上层节点随机选择下层节点。当然这个随机是比较而言的。

640.webp_(1)_.jpg

图 2 :传统的服务化架构,为伸缩性设计,上层节点随机选择下层节点


与其不同的是,在单元化架构下,服务虽然分层划分,但每个单元自成一体。按照层次来讲的话,所有层使用相同的分区算法,每一层都有相同数量的节点,上层节点也会访问指定的下层节点。因为他们已经在一起。

640.jpg

图 3 :单元化架构,为性能和隔离性而设计,上层节点访问指定下层节点


 
 2. 为什么要用单元化

在性能追求和成本限制的情况下,我们需要找到一种合适的方法来满足服务需求。在传统的分布式服务设计,我们考虑的更多是每个服务的可伸缩性,当各个服务独立设计时你就要在每一层进行伸缩性的考虑。这是服务化设计(SOA)流行的原因,我们需要每个服务能够单独水平扩展。
但是在摩尔定律下,随着硬件的不断升级,计算机硬件能力已经越来越强,CPU越来越快,内存越来越大,网络越来越宽。这让我们看到了在单台机器上垂直扩展的机会。尤其是当你遇到一个性能要求和容量增长可以预期的业务,单元化给我们提供另外的机会,让我们可以有效降低资源的使用,提供更高性能的服务。

总体而言,更高性能更低成本是我们的主要目标,而经过单元化改造,我们得以用更少(约二分之一)的机器,获得了比原来更高(接近百倍)的性能。性能的提升很大部分原因在于服务的本地化,而服务的集成部署又进一步降低了资源的使用。

当然除了性能收益,如果你做到了,你会发现还有很多收益,比如更好的隔离性,包括请求隔离和资源隔离,比如更友好的升级,产品可以灰度发布等。单元化改造后对高峰的应对以及扩容方式等问题,各位可以参考#微博春节技术保障系列#中的单元化架构文章,也不在此一一赘述。


3. 我们如何做到

此次单元化改造基于微博现有的业务,因此这里也先行介绍一下。粉丝服务平台是微博的内容推送系统(代号Castalia),可为V用户提供向其粉丝推送高质量内容的高速通道(单元化之后已到达百万条每秒)。整个服务涉及用户筛选、发送计费、屏蔽检查、限流控制和消息群发等多个子服务。由于改造思想相通,这里以用户筛选和消息群发两个服务为例,下面两图分别为商业群发在服务化思想和单元化思想下不同的架构。

640.webp_(2)_.jpg

图 4: 服务化思想下的商业群发架构设计(旧版)
640.webp_(3)_.jpg

图 5 :商业群发在单元化思想下的架构设计(新版)


对于筛选服务,在服务化架构里,需要去粉丝服务获取粉丝关系,然后去特征服务进行用户特征筛选,最后将筛选结果传输到群发服务器上;而在单元化架构里,粉丝关系直接就在本地文件中,用户特征服务也在本地,最后的筛选结果再不需要传输。服务本地化(粉丝关系和用户特征存储)减去了网络开销,降低了服务延时,还同时提高了访问速度和稳定性,而筛选结果本地存储又进一步节省了带宽并降低了延迟。以百万粉丝为例,每次网络操作的减少节省带宽8M左右,延时也从400ms降为0。

群发服务同样如此。由于在服务化架构里,我们使用MySQL和Memcache的方案,由于关系数据库的写入性能问题,中间还有队列以及相应的队列处理机,所有四个模块都有单独的机器提供服务,而在单元化架构里,四合一之后,只需要一套机器。当然机器的配置可能会有所提升,但真正计算之后你就会发现其实影响微乎其微。原因除了前面介绍的硬件增长空间外,上架机器的基本配置变高也是一个原因。而且,在单元化方案里,当我们把缓存部署在本地之后,其性能还有了额外的20%提升。


一些业务特有问题

不过群发这个场景,我们也遇到了一些特定的问题,一是分区问题,一是作业管理。这里也与各位分享下我们的解决方法。

分区问题分区问题其实是每个服务都会遇到的,但单元化后的挑战在于让所有服务都适配同一分区算法,在我们的场景下,我们按照接收者进行了分区,即从底层往上,每一层都来适配此分区算法。这里有特例的是用户特征和屏蔽服务,由于总体容量都很小,我们就没有对数据进行分区,所有单元内都是同一套全量数据,都是一个外部全量库的从库。不过由于本单元内的上层服务的关系,只有属于本分区的用户数据被访问到。所以,适配同一分区算法在某种程度上讲,可以兼容即可。

作业管理按照前面的分区方式,将群发服务的整体架构变成了一个类似Scatter-Gather+CQRS的方案,因为Gather不是一个请求处理的必须要素。也就是说,一个群发请求会被扩散到所有单元中,每个单元都要针对自己分区内的用户处理这个群发请求。广播方式的引入,使得我们首先需要在前端机进行分单元作业的处理监控,我们在此增加了持久化队列来解决。同时,由于单元内每个服务也都是单独维护的,作业可能在任何时间中断,因此每个作业在单元内的状态也都是有记录的,以此来达到作业的可重入和幂等性,也就可以保证每个作业都可以在任何时间重做,但不会重复执行。

除此之外,我们还对服务器进行了更为精细的控制,使用CPU绑定提高多服务集成部署时的整体效率,使用多硬盘设计保证每个服务的IO性能,通过主从单元的读写分离来提高整体服务等等。

后记

我平时不善文章,现在要成文发表,还是有一点紧张的。不过想到或许可以抛砖引玉,有机会向各位大牛学习,或者跟各位同学一起交流,内心又有些许期待。关于微博或者其他任何网站的设计,欢迎大家一起探讨,随时在微博恭候。

640.webp_(4)_.jpg

 
0
评论

【活动推荐】ECUG Con 2018 拥抱下一个十年 ECUG Con 2018 许式伟 ECUG 七牛云

beyond 发表了文章 • 87 次浏览 • 2018-12-03 15:47 • 来自相关话题

国内云计算领域大咖 许式伟
倾情发起的技术盛宴
引领国内云领域风向的高端峰会
ECUG Con 2018
2018 年 12 月 22-23 日 深圳
全新启程!ECUG Con 2018

七牛云 CEO 许式伟

PingCAP CEO 刘奇

七牛云产品副总裁戴文军

Gopher 社区创始人 Asta Xie

阿里巴巴技术专家孙宏亮

《Kubernetes IN ACTION》作者 Marko Lukša

华为云 AI 推理平台&云搜索技术总监胡斐然

七牛云技术总监陈超

阿里云高级开发工程师严明明

京东云区块链实验室与数据库部负责人郭里靖

网易研究院云计算资深架构师朱剑峰

腾讯云高级工程师刘兆瑞

货拉拉数据分析负责人高遥

......
超豪华讲师阵容!

超有料精彩分享!

ECUG 历经十年蜕变

邀您共同开启下个十年

让我们坚持技术情怀,秉承技术精神

开启新的云计算布道篇章!
 
时  间

2018 年 12 月 22-23 日

地  点

深圳市南山区软件产业基地 

更多详情请见下方海报~




扫描上方二维码 ,立即购买早鸟票

与大咖讲师共同探索云计算的下一个十年!
活动详情:了解更多 查看全部
国内云计算领域大咖  许式伟 
倾情发起的技术盛宴
引领国内云领域风向的高端峰会
ECUG Con 2018
2018 年 12 月 22-23 日 深圳
全新启程!
ECUG Con 2018

七牛云 CEO 许式伟

PingCAP CEO 刘奇

七牛云产品副总裁戴文军

Gopher 社区创始人 Asta Xie

阿里巴巴技术专家孙宏亮

《Kubernetes IN ACTION》作者 Marko Lukša

华为云 AI 推理平台&云搜索技术总监胡斐然

七牛云技术总监陈超

阿里云高级开发工程师严明明

京东云区块链实验室与数据库部负责人郭里靖

网易研究院云计算资深架构师朱剑峰

腾讯云高级工程师刘兆瑞

货拉拉数据分析负责人高遥

......
超豪华讲师阵容!

超有料精彩分享!

ECUG 历经十年蜕变

邀您共同开启下个十年

让我们坚持技术情怀,秉承技术精神

开启新的云计算布道篇章!
 
时  间

2018 年 12 月 22-23 日

地  点

深圳市南山区软件产业基地 

更多详情请见下方海报~
30943258454939062.jpg

扫描上方二维码 ,立即购买早鸟票

与大咖讲师共同探索云计算的下一个十年!
活动详情:了解更多
0
评论

【我最喜爱的 Cloud Studio 插件评选大赛】终于开始了! Cloud Studio Cloud Studio 插件评选大赛 腾讯云开发者平台 coding 编程大赛

beyond 发表了文章 • 137 次浏览 • 2018-11-26 15:37 • 来自相关话题

由 环信、腾讯云和 CODING 共同举办的 我最喜爱的 Cloud Studio 插件评选大赛正式开始了!在这场比赛里,将会有技术上的碰撞,大牛评委的专业点评,愉快的技术交流,好玩的插件尝试。





参赛者可以围绕 Git、实用小工具、腾讯云产品对接、UI 强化、语言支持等 14 个主题提交插件,再加上最具娱乐奖,代码最简单奖,设置功能最复杂奖等;近 30 种奖项,超高中奖率;插件只要提交上架,就有 50 元的话费相赠;只要关注 CODING 公众号并转发活动讯息到朋友圈,即可获得手机充值小礼!

参与方式

注册并登陆腾讯云开发者平台(https://dev.tencent.com) -> 点击进入活动页面 -> 点击进行插件的编写与提交(需要选择参与评选的类别)-> 审核无误后即可上架自动参与评选。

赛程时间




 
环信特别奖




基于环信开发一款聊天插件,即有机会获得特别奖,根据作品还将获得环信提供的神秘奖品
更多活动信息,请浏览我们的活动页面。

进入活动页面> 查看全部

2.jpg


由 环信、腾讯云和 CODING 共同举办的 我最喜爱的 Cloud Studio 插件评选大赛正式开始了!在这场比赛里,将会有技术上的碰撞,大牛评委的专业点评,愉快的技术交流,好玩的插件尝试。

6ccda21fgy1fxeim29mncj20ik0e6dn4.jpg

  • 参赛者可以围绕 Git、实用小工具、腾讯云产品对接、UI 强化、语言支持等 14 个主题提交插件,再加上最具娱乐奖,代码最简单奖,设置功能最复杂奖等;
  • 近 30 种奖项,超高中奖率;
  • 插件只要提交上架,就有 50 元的话费相赠;
  • 只要关注 CODING 公众号并转发活动讯息到朋友圈,即可获得手机充值小礼!


参与方式

注册并登陆腾讯云开发者平台https://dev.tencent.com) -> 点击进入活动页面 -> 点击进行插件的编写与提交(需要选择参与评选的类别)-> 审核无误后即可上架自动参与评选。

赛程时间
6ccda21fly1fxejmnr8oej20ow03odfy.jpg

 
环信特别奖
tb16@2x.png

基于环信开发一款聊天插件,即有机会获得特别奖,根据作品还将获得环信提供的神秘奖品
更多活动信息,请浏览我们的活动页面。

进入活动页面>
4
评论

【开源项目】全国首个开源直播小程序源码 环信公开课 小程序 直播

beyond 发表了文章 • 4026 次浏览 • 2018-07-20 17:30 • 来自相关话题

今天你看直播了吗?拥有10亿微信生态用户的小程序已经成为了继移动互联后的又一个现象级风口,随着微信小程序对外开放实时音视频录制及播放等更多连接能力,小程序与直播强强联合,在各行各业找到了非常多的玩法,小程序直播相比微信直播和APP直播更加简洁、流畅、低延时、多入口等众多优势迅速向商业直播领域及泛娱乐直播领域蔓延。从小游戏、内容付费、工具、大数据、社交电商创业者到传统品牌商们,都在努力搭上小程序直播这辆快车,以免错过微信生态里新的流量洼地。
 





作为一名环信生态圈资深开发者,本着对技术的热衷,对环信的眷恋和对党的忠诚,基于环信即时通讯云写了“直播购物小程序”,目前项目源码已全部免费开放,希望对有需求的企业和开发者提供一个思路和参考。
直播购物小程序源码github地址:https://github.com/YuTongNetworkTechnology/wechat_live/tree/master 
git打不开可直接点下面链接下载


小程序直播demo_2018-06-21.zip







直播购物小程序运行预览图 
 
小程序体验指南(仅需两步):
 
1、下载微信小程序开发工具,下载地址:https://developers.weixin.qq.c ... .html 
 




2、导入源码:将附件的源码解压直接导入 







环信小程序直播技术文档
一、 使用的技术
1、 环信IM直播室。
2、 微信小程序实时音视频播放组件live-player。
3、 推流软件(obs、易推流)等推流。
4、 视频流服务器(UCLOUD、七牛、腾讯)等视频流服务器。
二、 系统使用流程。
1、 视频推流软件将视频流推到流服务器。
2、 打开视频直播demo小程序注册环信账号。
3、 进入软件直播室进行测试。
三、 技术流程及使用的SDk
1、 注册环信账号
打开https://www.easemob.com/ 环信官网,点击右上角注册按钮,选择[注册即时通讯云]




填写对相关信息进行注册





注册成功后进行登录




注:新注册用户需进行账号的认证。
2、 直播应用创建
登录成功点击应用列表选择创建应用




输入应用名称等信息
 





创建成功后点击应用进入





需要注意的是应用的OrgName 和AppName这两个是以后都需要用到的两个参数变量




3、 直播创建
1)在创建直播之前需要对应用进行设置首先需要设置应用的直播流地址
第一步获取应用管理员的Tokencurl -X POST "https://a1.easemob.com/[应用OrgName]/[应用AppName]/token" -d '{"grant_type":"client_credentials","client_id":"[应用client_id]","client_secret":"[应用] client_secret"}'返回格式{
"access_token":"YWMtWY779DgJEeS2h9OR7fw4QgAAAUmO4Qukwd9cfJSpkWHiOa7MCSk0MrkVIco",
"expires_in":5184000,
"application":"c03b3e30-046a-11e4-8ed1-5701cdaaa0e4"












第二步设置直播流地址curl -X POST -H "Authorization: Bearer [管理员Token]" " https://a1.easemob.com/[应用OrgName]/[应用AppName]/liverooms/stream_url -d '{"pc_pull":"[pc拉流地址]","pc_push":"[pc推流地址]","mobile_pull":"[手机拉流地址]","mobile_push":"[手机推流地址]"}'"成功返回格式:{
"action": "post",
"application": "e1a09de0-0e03-11e7-ad8e-a1d913615409",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"pc_pull": true,
"mobile_push": true,
"mobile_pull": true,
"pc_push": true
},
"timestamp": 1494084474885,
"duration": 1,
"organization": "easemob-demo",
"applicationName": "chatdemoui"
}












2)创建主播
点击IM用户





点击注册IM用户





填写用户信息





创建用户的过程同样也可以通过REST API形式进行curl -X POST -i " https://a1.easemob.com/[应用OrgName]/[应用AppName]/users" -d '{"username":"[用户名]","password":"[密码]"}'
注:应用必须为开放注册





将注册的用户添加为主播curl -X POST -H "Authorization: [管理员Token]" https://a1.easemob.com/[应用OrgName]/[应用AppName]/super_admin -d'{"superadmin":"[IM用户名]"}'返回结果示例:{
"action": "post",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"result": "success"
},
"timestamp": 1496236798886,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui"
}












3)创建直播
点击直播





点击新建房间





填写房间信息




创建房间同时也可以使用REST API形式进行详情可以查看http://docs.easemob.com/im/live/server-integration环信官方文档。
4、 小程序demo集成使用
小程序直播购物demo集成官方WebIM SDK详情请查看https://github.com/easemob/webim-weixin-xcx
Demo具体配置如下
打开demo 下sdk配置文件





修改appkey为自己应用的appkey





打开pages/live/index.js修改房间默认拉流地址及直播间房间号





四、 扩展说明
Demo中房间为固定测试房间,实际使用中应获取环信直播的房间信息及房间列表。具体如下:
获取直播间列表:curl -X GET -H "Authorization: Bearer [用户Token]" https://a1.easemob.com/[应用OrgName]/[应用AppName]/liverooms?ongoing=true&limit=[获取数量]&cursor=[游标地址(不填写为充开始查询)]
响应:{
"action": "get",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"params": {
"cursor": [
"ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aW06Y2hhdHJvb206ZWFzZW1vYi1kZW1vI2NoYXRkZW1vdWk6MzE"
],
"ongoing": [
"true"
],
"limit": [
"2"
]
},
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": [
{
"id": "1924",
"chatroom_id": "17177265635330",
"title": "具体了",
"desc": "就咯",
"startTime": 1495779917352,
"endTime": 1495779917352,
"anchor": "wuls",
"gift_count": 0,
"praise_count": 0,
"current_user_count": 8,
"max_user_count": 9,
"status": "ongoing",
"cover_picture_url": "",
"pc_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"pc_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"mobile_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"mobile_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1"
},
{
"id": "1922",
"chatroom_id": "17175003856897",
"title": "香山",
"desc": "随便",
"startTime": 1495777760957,
"endTime": 1495777760957,
"anchor": "sx001",
"gift_count": 0,
"praise_count": 8,
"current_user_count": 1,
"max_user_count": 3,
"status": "ongoing",
"cover_picture_url": "http://127.0.0.1:8080/easemob- ... ot%3B,
"pc_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"pc_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"mobile_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"mobile_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1"
}
],
"timestamp": 1496303336669,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui",
"cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aW06Y2hhdHJvb206ZWFzZW1vYi1kZW1vI2NoYXRkZW1vdWk6NDk",
"count": 2
}












获取直播间详情:curl -X GET -H "Authorization: Bearer [用户Token]" " https://a1.easemob.com/[应用OrgName]/[应用AppName]/[房间id]/status"响应:{
"action": "get",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"liveRoomID": "1946",
"status": "ongoing"
},
"timestamp": 1496234759930,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui",
"count": 0
}














 
使用环信直播购物小程序遇到任何问题欢迎跟帖讨论。 查看全部
今天你看直播了吗?
拥有10亿微信生态用户的小程序已经成为了继移动互联后的又一个现象级风口,随着微信小程序对外开放实时音视频录制及播放等更多连接能力,小程序与直播强强联合,在各行各业找到了非常多的玩法,小程序直播相比微信直播和APP直播更加简洁、流畅、低延时、多入口等众多优势迅速向商业直播领域及泛娱乐直播领域蔓延。从小游戏、内容付费、工具、大数据、社交电商创业者到传统品牌商们,都在努力搭上小程序直播这辆快车,以免错过微信生态里新的流量洼地。
 
微信图片_20180725162426.jpg


作为一名环信生态圈资深开发者,本着对技术的热衷,对环信的眷恋和对党的忠诚,基于环信即时通讯云写了“直播购物小程序”,目前项目源码已全部免费开放,希望对有需求的企业和开发者提供一个思路和参考。
直播购物小程序源码github地址:https://github.com/YuTongNetworkTechnology/wechat_live/tree/master 
git打不开可直接点下面链接下载



预览图.jpg

直播购物小程序运行预览图 
 
小程序体验指南(仅需两步):
 
1、下载微信小程序开发工具,下载地址:https://developers.weixin.qq.c ... .html 
 
Catch9A07(07-20-17-38-30).jpg

2、导入源码:将附件的源码解压直接导入 


Catch1C69(07-20-17-38-30).jpg


环信小程序直播技术文档
一、 使用的技术
1、 环信IM直播室。
2、 微信小程序实时音视频播放组件live-player。
3、 推流软件(obs、易推流)等推流。
4、 视频流服务器(UCLOUD、七牛、腾讯)等视频流服务器。
二、 系统使用流程。
1、 视频推流软件将视频流推到流服务器。
2、 打开视频直播demo小程序注册环信账号。
3、 进入软件直播室进行测试。
三、 技术流程及使用的SDk
1、 注册环信账号
打开https://www.easemob.com/ 环信官网,点击右上角注册按钮,选择[注册即时通讯云]
1.png

填写对相关信息进行注册

2.png

注册成功后进行登录
3.png

注:新注册用户需进行账号的认证。
2、 直播应用创建
登录成功点击应用列表选择创建应用
4.png

输入应用名称等信息
 

5.png

创建成功后点击应用进入

6.png

需要注意的是应用的OrgName 和AppName这两个是以后都需要用到的两个参数变量
7.png

3、 直播创建
1)在创建直播之前需要对应用进行设置首先需要设置应用的直播流地址
第一步获取应用管理员的Token
curl -X POST "https://a1.easemob.com/[应用OrgName]/[应用AppName]/token" -d '{"grant_type":"client_credentials","client_id":"[应用client_id]","client_secret":"[应用] client_secret"}'
返回格式
{
"access_token":"YWMtWY779DgJEeS2h9OR7fw4QgAAAUmO4Qukwd9cfJSpkWHiOa7MCSk0MrkVIco",
"expires_in":5184000,
"application":"c03b3e30-046a-11e4-8ed1-5701cdaaa0e4"












第二步设置直播流地址
curl -X POST -H "Authorization: Bearer [管理员Token]"  " https://a1.easemob.com/[应用OrgName]/[应用AppName]/liverooms/stream_url -d '{"pc_pull":"[pc拉流地址]","pc_push":"[pc推流地址]","mobile_pull":"[手机拉流地址]","mobile_push":"[手机推流地址]"}'"
成功返回格式:
{
"action": "post",
"application": "e1a09de0-0e03-11e7-ad8e-a1d913615409",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"pc_pull": true,
"mobile_push": true,
"mobile_pull": true,
"pc_push": true
},
"timestamp": 1494084474885,
"duration": 1,
"organization": "easemob-demo",
"applicationName": "chatdemoui"
}












2)创建主播
点击IM用户

8.png

点击注册IM用户

9.png

填写用户信息

10.png

创建用户的过程同样也可以通过REST API形式进行
curl -X POST -i " https://a1.easemob.com/[应用OrgName]/[应用AppName]/users" -d '{"username":"[用户名]","password":"[密码]"}'

注:应用必须为开放注册

11.png

将注册的用户添加为主播
curl -X POST -H "Authorization: [管理员Token]"  https://a1.easemob.com/[应用OrgName]/[应用AppName]/super_admin -d'{"superadmin":"[IM用户名]"}'
返回结果示例:
{
"action": "post",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"result": "success"
},
"timestamp": 1496236798886,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui"
}












3)创建直播
点击直播

12.png

点击新建房间

13.png

填写房间信息
14.png

创建房间同时也可以使用REST API形式进行详情可以查看http://docs.easemob.com/im/live/server-integration环信官方文档。
4、 小程序demo集成使用
小程序直播购物demo集成官方WebIM SDK详情请查看https://github.com/easemob/webim-weixin-xcx
Demo具体配置如下
打开demo 下sdk配置文件

15.png

修改appkey为自己应用的appkey

16.png

打开pages/live/index.js修改房间默认拉流地址及直播间房间号

17.png

四、 扩展说明
Demo中房间为固定测试房间,实际使用中应获取环信直播的房间信息及房间列表。具体如下:
获取直播间列表:
curl -X GET -H "Authorization: Bearer  [用户Token]"  https://a1.easemob.com/[应用OrgName]/[应用AppName]/liverooms?ongoing=true&limit=[获取数量]&cursor=[游标地址(不填写为充开始查询)]

响应:
{
"action": "get",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"params": {
"cursor": [
"ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aW06Y2hhdHJvb206ZWFzZW1vYi1kZW1vI2NoYXRkZW1vdWk6MzE"
],
"ongoing": [
"true"
],
"limit": [
"2"
]
},
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": [
{
"id": "1924",
"chatroom_id": "17177265635330",
"title": "具体了",
"desc": "就咯",
"startTime": 1495779917352,
"endTime": 1495779917352,
"anchor": "wuls",
"gift_count": 0,
"praise_count": 0,
"current_user_count": 8,
"max_user_count": 9,
"status": "ongoing",
"cover_picture_url": "",
"pc_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"pc_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"mobile_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"mobile_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1"
},
{
"id": "1922",
"chatroom_id": "17175003856897",
"title": "香山",
"desc": "随便",
"startTime": 1495777760957,
"endTime": 1495777760957,
"anchor": "sx001",
"gift_count": 0,
"praise_count": 8,
"current_user_count": 1,
"max_user_count": 3,
"status": "ongoing",
"cover_picture_url": "http://127.0.0.1:8080/easemob- ... ot%3B,
"pc_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"pc_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"mobile_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"mobile_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1"
}
],
"timestamp": 1496303336669,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui",
"cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aW06Y2hhdHJvb206ZWFzZW1vYi1kZW1vI2NoYXRkZW1vdWk6NDk",
"count": 2
}












获取直播间详情:
curl -X GET -H "Authorization: Bearer [用户Token]" " https://a1.easemob.com/[应用OrgName]/[应用AppName]/[房间id]/status"
响应:
{
"action": "get",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"liveRoomID": "1946",
"status": "ongoing"
},
"timestamp": 1496234759930,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui",
"count": 0
}














 
使用环信直播购物小程序遇到任何问题欢迎跟帖讨论。
19
评论

【新手快速入门】集成环信常见问题+解决方案汇总 常见问题

dujiepeng 发表了文章 • 18351 次浏览 • 2017-05-22 15:51 • 来自相关话题

   这里整理了集成环信的常见问题和一些功能的实现思路,希望能帮助到大家。感谢热心的开发者贡献,大家在观看过程中有不明白的地方欢迎直接跟帖咨询。
 
ios篇
APNs证书创建和上传到环信后台头像昵称的简述和处理方案音视频离线推送Demo实现环信服务器聊天记录保存多久?离线收不到好友请求IOS中环信聊天窗口如何实现文件发送和预览的功能ios集成常见问题环信推送的一些常见问题实现名片|红包|话题聊天室等自定义cell
 
Android篇
Android sdk 的两种导入方式环信3.0SDK集成小米推送教程EaseUI库中V4、v7包冲突解决方案Android EaseUI里的百度地图替换为高德地图android扩展消息(名片集成)关于会话列表的置顶聊天java.lang.UnsatisfiedLinkError: 的问题android 端 app 后台被杀死收不到消息的解决方案
昵称头像篇
android中如何显示开发者服务器上的昵称和头像 Android中显示头像(接上一篇文章看)环信(Android)设置头像和昵称的方法(最简单暴力的基于环信demo的集成)IOS中如何显示开发者服务器上的昵称和头像【环信公开课第12期视频回放】-所有关于环信IM昵称头像的问题听这课就够了
 
直播篇
一言不合你就搞个直播APP
 
客服集成
IM-SDK和客服SDK并存开发指南—Android篇IM-SDK和客服SDK并存开发指南—iOS篇
 
开源项目
Android简版demoios简版demo凡信2.0:超仿微信的开源项目 凡信3.0:携直播和红包而来高仿微信:Github 3,515 Star方圆十里:环信编程大赛冠军项目泛聊:定一个小目标写一个QQSlack聊天机器人:一天时间做一个聊天机器人TV视频通话:在电视上视频通话视频通话:Android手机视频通话酷信:ios高仿微信公众号助手:与订阅用户聊天沟通
 
持续更新ing...小伙伴们还有什么想知道欢迎跟帖提出。
  查看全部
   这里整理了集成环信的常见问题和一些功能的实现思路,希望能帮助到大家。感谢热心的开发者贡献,大家在观看过程中有不明白的地方欢迎直接跟帖咨询。
 
ios篇

 
Android篇

昵称头像篇

 
直播篇
  1. 一言不合你就搞个直播APP

 
客服集成
  1. IM-SDK和客服SDK并存开发指南—Android篇
  2. IM-SDK和客服SDK并存开发指南—iOS篇

 
开源项目

 
持续更新ing...小伙伴们还有什么想知道欢迎跟帖提出。
 
11
回复

收集基于环信SDK开发的开源项目 开源项目

xiaoyan2015 回复了问题 • 13 人关注 • 11728 次浏览 • 2018-11-21 23:59 • 来自相关话题

0
评论

【活动推荐】ECUG Con 2018 拥抱下一个十年 ECUG Con 2018 许式伟 ECUG 七牛云

beyond 发表了文章 • 87 次浏览 • 2018-12-03 15:47 • 来自相关话题

国内云计算领域大咖 许式伟
倾情发起的技术盛宴
引领国内云领域风向的高端峰会
ECUG Con 2018
2018 年 12 月 22-23 日 深圳
全新启程!ECUG Con 2018

七牛云 CEO 许式伟

PingCAP CEO 刘奇

七牛云产品副总裁戴文军

Gopher 社区创始人 Asta Xie

阿里巴巴技术专家孙宏亮

《Kubernetes IN ACTION》作者 Marko Lukša

华为云 AI 推理平台&云搜索技术总监胡斐然

七牛云技术总监陈超

阿里云高级开发工程师严明明

京东云区块链实验室与数据库部负责人郭里靖

网易研究院云计算资深架构师朱剑峰

腾讯云高级工程师刘兆瑞

货拉拉数据分析负责人高遥

......
超豪华讲师阵容!

超有料精彩分享!

ECUG 历经十年蜕变

邀您共同开启下个十年

让我们坚持技术情怀,秉承技术精神

开启新的云计算布道篇章!
 
时  间

2018 年 12 月 22-23 日

地  点

深圳市南山区软件产业基地 

更多详情请见下方海报~




扫描上方二维码 ,立即购买早鸟票

与大咖讲师共同探索云计算的下一个十年!
活动详情:了解更多 查看全部
国内云计算领域大咖  许式伟 
倾情发起的技术盛宴
引领国内云领域风向的高端峰会
ECUG Con 2018
2018 年 12 月 22-23 日 深圳
全新启程!
ECUG Con 2018

七牛云 CEO 许式伟

PingCAP CEO 刘奇

七牛云产品副总裁戴文军

Gopher 社区创始人 Asta Xie

阿里巴巴技术专家孙宏亮

《Kubernetes IN ACTION》作者 Marko Lukša

华为云 AI 推理平台&云搜索技术总监胡斐然

七牛云技术总监陈超

阿里云高级开发工程师严明明

京东云区块链实验室与数据库部负责人郭里靖

网易研究院云计算资深架构师朱剑峰

腾讯云高级工程师刘兆瑞

货拉拉数据分析负责人高遥

......
超豪华讲师阵容!

超有料精彩分享!

ECUG 历经十年蜕变

邀您共同开启下个十年

让我们坚持技术情怀,秉承技术精神

开启新的云计算布道篇章!
 
时  间

2018 年 12 月 22-23 日

地  点

深圳市南山区软件产业基地 

更多详情请见下方海报~
30943258454939062.jpg

扫描上方二维码 ,立即购买早鸟票

与大咖讲师共同探索云计算的下一个十年!
活动详情:了解更多
0
评论

【我最喜爱的 Cloud Studio 插件评选大赛】终于开始了! Cloud Studio Cloud Studio 插件评选大赛 腾讯云开发者平台 coding 编程大赛

beyond 发表了文章 • 137 次浏览 • 2018-11-26 15:37 • 来自相关话题

由 环信、腾讯云和 CODING 共同举办的 我最喜爱的 Cloud Studio 插件评选大赛正式开始了!在这场比赛里,将会有技术上的碰撞,大牛评委的专业点评,愉快的技术交流,好玩的插件尝试。





参赛者可以围绕 Git、实用小工具、腾讯云产品对接、UI 强化、语言支持等 14 个主题提交插件,再加上最具娱乐奖,代码最简单奖,设置功能最复杂奖等;近 30 种奖项,超高中奖率;插件只要提交上架,就有 50 元的话费相赠;只要关注 CODING 公众号并转发活动讯息到朋友圈,即可获得手机充值小礼!

参与方式

注册并登陆腾讯云开发者平台(https://dev.tencent.com) -> 点击进入活动页面 -> 点击进行插件的编写与提交(需要选择参与评选的类别)-> 审核无误后即可上架自动参与评选。

赛程时间




 
环信特别奖




基于环信开发一款聊天插件,即有机会获得特别奖,根据作品还将获得环信提供的神秘奖品
更多活动信息,请浏览我们的活动页面。

进入活动页面> 查看全部

2.jpg


由 环信、腾讯云和 CODING 共同举办的 我最喜爱的 Cloud Studio 插件评选大赛正式开始了!在这场比赛里,将会有技术上的碰撞,大牛评委的专业点评,愉快的技术交流,好玩的插件尝试。

6ccda21fgy1fxeim29mncj20ik0e6dn4.jpg

  • 参赛者可以围绕 Git、实用小工具、腾讯云产品对接、UI 强化、语言支持等 14 个主题提交插件,再加上最具娱乐奖,代码最简单奖,设置功能最复杂奖等;
  • 近 30 种奖项,超高中奖率;
  • 插件只要提交上架,就有 50 元的话费相赠;
  • 只要关注 CODING 公众号并转发活动讯息到朋友圈,即可获得手机充值小礼!


参与方式

注册并登陆腾讯云开发者平台https://dev.tencent.com) -> 点击进入活动页面 -> 点击进行插件的编写与提交(需要选择参与评选的类别)-> 审核无误后即可上架自动参与评选。

赛程时间
6ccda21fly1fxejmnr8oej20ow03odfy.jpg

 
环信特别奖
tb16@2x.png

基于环信开发一款聊天插件,即有机会获得特别奖,根据作品还将获得环信提供的神秘奖品
更多活动信息,请浏览我们的活动页面。

进入活动页面>
11
回复

收集基于环信SDK开发的开源项目 开源项目

回复

xiaoyan2015 回复了问题 • 13 人关注 • 11728 次浏览 • 2018-11-21 23:59 • 来自相关话题

4
评论

【开源项目】全国首个开源直播小程序源码 环信公开课 小程序 直播

beyond 发表了文章 • 4026 次浏览 • 2018-07-20 17:30 • 来自相关话题

今天你看直播了吗?拥有10亿微信生态用户的小程序已经成为了继移动互联后的又一个现象级风口,随着微信小程序对外开放实时音视频录制及播放等更多连接能力,小程序与直播强强联合,在各行各业找到了非常多的玩法,小程序直播相比微信直播和APP直播更加简洁、流畅、低延时、多入口等众多优势迅速向商业直播领域及泛娱乐直播领域蔓延。从小游戏、内容付费、工具、大数据、社交电商创业者到传统品牌商们,都在努力搭上小程序直播这辆快车,以免错过微信生态里新的流量洼地。
 





作为一名环信生态圈资深开发者,本着对技术的热衷,对环信的眷恋和对党的忠诚,基于环信即时通讯云写了“直播购物小程序”,目前项目源码已全部免费开放,希望对有需求的企业和开发者提供一个思路和参考。
直播购物小程序源码github地址:https://github.com/YuTongNetworkTechnology/wechat_live/tree/master 
git打不开可直接点下面链接下载


小程序直播demo_2018-06-21.zip







直播购物小程序运行预览图 
 
小程序体验指南(仅需两步):
 
1、下载微信小程序开发工具,下载地址:https://developers.weixin.qq.c ... .html 
 




2、导入源码:将附件的源码解压直接导入 







环信小程序直播技术文档
一、 使用的技术
1、 环信IM直播室。
2、 微信小程序实时音视频播放组件live-player。
3、 推流软件(obs、易推流)等推流。
4、 视频流服务器(UCLOUD、七牛、腾讯)等视频流服务器。
二、 系统使用流程。
1、 视频推流软件将视频流推到流服务器。
2、 打开视频直播demo小程序注册环信账号。
3、 进入软件直播室进行测试。
三、 技术流程及使用的SDk
1、 注册环信账号
打开https://www.easemob.com/ 环信官网,点击右上角注册按钮,选择[注册即时通讯云]




填写对相关信息进行注册





注册成功后进行登录




注:新注册用户需进行账号的认证。
2、 直播应用创建
登录成功点击应用列表选择创建应用




输入应用名称等信息
 





创建成功后点击应用进入





需要注意的是应用的OrgName 和AppName这两个是以后都需要用到的两个参数变量




3、 直播创建
1)在创建直播之前需要对应用进行设置首先需要设置应用的直播流地址
第一步获取应用管理员的Tokencurl -X POST "https://a1.easemob.com/[应用OrgName]/[应用AppName]/token" -d '{"grant_type":"client_credentials","client_id":"[应用client_id]","client_secret":"[应用] client_secret"}'返回格式{
"access_token":"YWMtWY779DgJEeS2h9OR7fw4QgAAAUmO4Qukwd9cfJSpkWHiOa7MCSk0MrkVIco",
"expires_in":5184000,
"application":"c03b3e30-046a-11e4-8ed1-5701cdaaa0e4"












第二步设置直播流地址curl -X POST -H "Authorization: Bearer [管理员Token]" " https://a1.easemob.com/[应用OrgName]/[应用AppName]/liverooms/stream_url -d '{"pc_pull":"[pc拉流地址]","pc_push":"[pc推流地址]","mobile_pull":"[手机拉流地址]","mobile_push":"[手机推流地址]"}'"成功返回格式:{
"action": "post",
"application": "e1a09de0-0e03-11e7-ad8e-a1d913615409",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"pc_pull": true,
"mobile_push": true,
"mobile_pull": true,
"pc_push": true
},
"timestamp": 1494084474885,
"duration": 1,
"organization": "easemob-demo",
"applicationName": "chatdemoui"
}












2)创建主播
点击IM用户





点击注册IM用户





填写用户信息





创建用户的过程同样也可以通过REST API形式进行curl -X POST -i " https://a1.easemob.com/[应用OrgName]/[应用AppName]/users" -d '{"username":"[用户名]","password":"[密码]"}'
注:应用必须为开放注册





将注册的用户添加为主播curl -X POST -H "Authorization: [管理员Token]" https://a1.easemob.com/[应用OrgName]/[应用AppName]/super_admin -d'{"superadmin":"[IM用户名]"}'返回结果示例:{
"action": "post",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"result": "success"
},
"timestamp": 1496236798886,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui"
}












3)创建直播
点击直播





点击新建房间





填写房间信息




创建房间同时也可以使用REST API形式进行详情可以查看http://docs.easemob.com/im/live/server-integration环信官方文档。
4、 小程序demo集成使用
小程序直播购物demo集成官方WebIM SDK详情请查看https://github.com/easemob/webim-weixin-xcx
Demo具体配置如下
打开demo 下sdk配置文件





修改appkey为自己应用的appkey





打开pages/live/index.js修改房间默认拉流地址及直播间房间号





四、 扩展说明
Demo中房间为固定测试房间,实际使用中应获取环信直播的房间信息及房间列表。具体如下:
获取直播间列表:curl -X GET -H "Authorization: Bearer [用户Token]" https://a1.easemob.com/[应用OrgName]/[应用AppName]/liverooms?ongoing=true&limit=[获取数量]&cursor=[游标地址(不填写为充开始查询)]
响应:{
"action": "get",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"params": {
"cursor": [
"ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aW06Y2hhdHJvb206ZWFzZW1vYi1kZW1vI2NoYXRkZW1vdWk6MzE"
],
"ongoing": [
"true"
],
"limit": [
"2"
]
},
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": [
{
"id": "1924",
"chatroom_id": "17177265635330",
"title": "具体了",
"desc": "就咯",
"startTime": 1495779917352,
"endTime": 1495779917352,
"anchor": "wuls",
"gift_count": 0,
"praise_count": 0,
"current_user_count": 8,
"max_user_count": 9,
"status": "ongoing",
"cover_picture_url": "",
"pc_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"pc_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"mobile_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"mobile_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1"
},
{
"id": "1922",
"chatroom_id": "17175003856897",
"title": "香山",
"desc": "随便",
"startTime": 1495777760957,
"endTime": 1495777760957,
"anchor": "sx001",
"gift_count": 0,
"praise_count": 8,
"current_user_count": 1,
"max_user_count": 3,
"status": "ongoing",
"cover_picture_url": "http://127.0.0.1:8080/easemob- ... ot%3B,
"pc_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"pc_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"mobile_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"mobile_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1"
}
],
"timestamp": 1496303336669,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui",
"cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aW06Y2hhdHJvb206ZWFzZW1vYi1kZW1vI2NoYXRkZW1vdWk6NDk",
"count": 2
}












获取直播间详情:curl -X GET -H "Authorization: Bearer [用户Token]" " https://a1.easemob.com/[应用OrgName]/[应用AppName]/[房间id]/status"响应:{
"action": "get",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"liveRoomID": "1946",
"status": "ongoing"
},
"timestamp": 1496234759930,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui",
"count": 0
}














 
使用环信直播购物小程序遇到任何问题欢迎跟帖讨论。 查看全部
今天你看直播了吗?
拥有10亿微信生态用户的小程序已经成为了继移动互联后的又一个现象级风口,随着微信小程序对外开放实时音视频录制及播放等更多连接能力,小程序与直播强强联合,在各行各业找到了非常多的玩法,小程序直播相比微信直播和APP直播更加简洁、流畅、低延时、多入口等众多优势迅速向商业直播领域及泛娱乐直播领域蔓延。从小游戏、内容付费、工具、大数据、社交电商创业者到传统品牌商们,都在努力搭上小程序直播这辆快车,以免错过微信生态里新的流量洼地。
 
微信图片_20180725162426.jpg


作为一名环信生态圈资深开发者,本着对技术的热衷,对环信的眷恋和对党的忠诚,基于环信即时通讯云写了“直播购物小程序”,目前项目源码已全部免费开放,希望对有需求的企业和开发者提供一个思路和参考。
直播购物小程序源码github地址:https://github.com/YuTongNetworkTechnology/wechat_live/tree/master 
git打不开可直接点下面链接下载



预览图.jpg

直播购物小程序运行预览图 
 
小程序体验指南(仅需两步):
 
1、下载微信小程序开发工具,下载地址:https://developers.weixin.qq.c ... .html 
 
Catch9A07(07-20-17-38-30).jpg

2、导入源码:将附件的源码解压直接导入 


Catch1C69(07-20-17-38-30).jpg


环信小程序直播技术文档
一、 使用的技术
1、 环信IM直播室。
2、 微信小程序实时音视频播放组件live-player。
3、 推流软件(obs、易推流)等推流。
4、 视频流服务器(UCLOUD、七牛、腾讯)等视频流服务器。
二、 系统使用流程。
1、 视频推流软件将视频流推到流服务器。
2、 打开视频直播demo小程序注册环信账号。
3、 进入软件直播室进行测试。
三、 技术流程及使用的SDk
1、 注册环信账号
打开https://www.easemob.com/ 环信官网,点击右上角注册按钮,选择[注册即时通讯云]
1.png

填写对相关信息进行注册

2.png

注册成功后进行登录
3.png

注:新注册用户需进行账号的认证。
2、 直播应用创建
登录成功点击应用列表选择创建应用
4.png

输入应用名称等信息
 

5.png

创建成功后点击应用进入

6.png

需要注意的是应用的OrgName 和AppName这两个是以后都需要用到的两个参数变量
7.png

3、 直播创建
1)在创建直播之前需要对应用进行设置首先需要设置应用的直播流地址
第一步获取应用管理员的Token
curl -X POST "https://a1.easemob.com/[应用OrgName]/[应用AppName]/token" -d '{"grant_type":"client_credentials","client_id":"[应用client_id]","client_secret":"[应用] client_secret"}'
返回格式
{
"access_token":"YWMtWY779DgJEeS2h9OR7fw4QgAAAUmO4Qukwd9cfJSpkWHiOa7MCSk0MrkVIco",
"expires_in":5184000,
"application":"c03b3e30-046a-11e4-8ed1-5701cdaaa0e4"












第二步设置直播流地址
curl -X POST -H "Authorization: Bearer [管理员Token]"  " https://a1.easemob.com/[应用OrgName]/[应用AppName]/liverooms/stream_url -d '{"pc_pull":"[pc拉流地址]","pc_push":"[pc推流地址]","mobile_pull":"[手机拉流地址]","mobile_push":"[手机推流地址]"}'"
成功返回格式:
{
"action": "post",
"application": "e1a09de0-0e03-11e7-ad8e-a1d913615409",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"pc_pull": true,
"mobile_push": true,
"mobile_pull": true,
"pc_push": true
},
"timestamp": 1494084474885,
"duration": 1,
"organization": "easemob-demo",
"applicationName": "chatdemoui"
}












2)创建主播
点击IM用户

8.png

点击注册IM用户

9.png

填写用户信息

10.png

创建用户的过程同样也可以通过REST API形式进行
curl -X POST -i " https://a1.easemob.com/[应用OrgName]/[应用AppName]/users" -d '{"username":"[用户名]","password":"[密码]"}'

注:应用必须为开放注册

11.png

将注册的用户添加为主播
curl -X POST -H "Authorization: [管理员Token]"  https://a1.easemob.com/[应用OrgName]/[应用AppName]/super_admin -d'{"superadmin":"[IM用户名]"}'
返回结果示例:
{
"action": "post",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"result": "success"
},
"timestamp": 1496236798886,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui"
}












3)创建直播
点击直播

12.png

点击新建房间

13.png

填写房间信息
14.png

创建房间同时也可以使用REST API形式进行详情可以查看http://docs.easemob.com/im/live/server-integration环信官方文档。
4、 小程序demo集成使用
小程序直播购物demo集成官方WebIM SDK详情请查看https://github.com/easemob/webim-weixin-xcx
Demo具体配置如下
打开demo 下sdk配置文件

15.png

修改appkey为自己应用的appkey

16.png

打开pages/live/index.js修改房间默认拉流地址及直播间房间号

17.png

四、 扩展说明
Demo中房间为固定测试房间,实际使用中应获取环信直播的房间信息及房间列表。具体如下:
获取直播间列表:
curl -X GET -H "Authorization: Bearer  [用户Token]"  https://a1.easemob.com/[应用OrgName]/[应用AppName]/liverooms?ongoing=true&limit=[获取数量]&cursor=[游标地址(不填写为充开始查询)]

响应:
{
"action": "get",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"params": {
"cursor": [
"ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aW06Y2hhdHJvb206ZWFzZW1vYi1kZW1vI2NoYXRkZW1vdWk6MzE"
],
"ongoing": [
"true"
],
"limit": [
"2"
]
},
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": [
{
"id": "1924",
"chatroom_id": "17177265635330",
"title": "具体了",
"desc": "就咯",
"startTime": 1495779917352,
"endTime": 1495779917352,
"anchor": "wuls",
"gift_count": 0,
"praise_count": 0,
"current_user_count": 8,
"max_user_count": 9,
"status": "ongoing",
"cover_picture_url": "",
"pc_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"pc_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"mobile_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1",
"mobile_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1924_1"
},
{
"id": "1922",
"chatroom_id": "17175003856897",
"title": "香山",
"desc": "随便",
"startTime": 1495777760957,
"endTime": 1495777760957,
"anchor": "sx001",
"gift_count": 0,
"praise_count": 8,
"current_user_count": 1,
"max_user_count": 3,
"status": "ongoing",
"cover_picture_url": "http://127.0.0.1:8080/easemob- ... ot%3B,
"pc_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"pc_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"mobile_pull_url": "rtmp://vlive3.rtmp.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1",
"mobile_push_url": "rtmp://publish3.cdn.ucloud.com.cn/ucloud/easemob-demo_chatdemoui_1922_1"
}
],
"timestamp": 1496303336669,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui",
"cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aW06Y2hhdHJvb206ZWFzZW1vYi1kZW1vI2NoYXRkZW1vdWk6NDk",
"count": 2
}












获取直播间详情:
curl -X GET -H "Authorization: Bearer [用户Token]" " https://a1.easemob.com/[应用OrgName]/[应用AppName]/[房间id]/status"
响应:
{
"action": "get",
"application": "4d7e4ba0-dc4a-11e3-90d5-e1ffbaacdaf5",
"uri": "http://127.0.0.1:8080/easemob- ... ot%3B,
"entities": [ ],
"data": {
"liveRoomID": "1946",
"status": "ongoing"
},
"timestamp": 1496234759930,
"duration": 0,
"organization": "easemob-demo",
"applicationName": "chatdemoui",
"count": 0
}














 
使用环信直播购物小程序遇到任何问题欢迎跟帖讨论。
19
评论

【新手快速入门】集成环信常见问题+解决方案汇总 常见问题

dujiepeng 发表了文章 • 18351 次浏览 • 2017-05-22 15:51 • 来自相关话题

   这里整理了集成环信的常见问题和一些功能的实现思路,希望能帮助到大家。感谢热心的开发者贡献,大家在观看过程中有不明白的地方欢迎直接跟帖咨询。
 
ios篇
APNs证书创建和上传到环信后台头像昵称的简述和处理方案音视频离线推送Demo实现环信服务器聊天记录保存多久?离线收不到好友请求IOS中环信聊天窗口如何实现文件发送和预览的功能ios集成常见问题环信推送的一些常见问题实现名片|红包|话题聊天室等自定义cell
 
Android篇
Android sdk 的两种导入方式环信3.0SDK集成小米推送教程EaseUI库中V4、v7包冲突解决方案Android EaseUI里的百度地图替换为高德地图android扩展消息(名片集成)关于会话列表的置顶聊天java.lang.UnsatisfiedLinkError: 的问题android 端 app 后台被杀死收不到消息的解决方案
昵称头像篇
android中如何显示开发者服务器上的昵称和头像 Android中显示头像(接上一篇文章看)环信(Android)设置头像和昵称的方法(最简单暴力的基于环信demo的集成)IOS中如何显示开发者服务器上的昵称和头像【环信公开课第12期视频回放】-所有关于环信IM昵称头像的问题听这课就够了
 
直播篇
一言不合你就搞个直播APP
 
客服集成
IM-SDK和客服SDK并存开发指南—Android篇IM-SDK和客服SDK并存开发指南—iOS篇
 
开源项目
Android简版demoios简版demo凡信2.0:超仿微信的开源项目 凡信3.0:携直播和红包而来高仿微信:Github 3,515 Star方圆十里:环信编程大赛冠军项目泛聊:定一个小目标写一个QQSlack聊天机器人:一天时间做一个聊天机器人TV视频通话:在电视上视频通话视频通话:Android手机视频通话酷信:ios高仿微信公众号助手:与订阅用户聊天沟通
 
持续更新ing...小伙伴们还有什么想知道欢迎跟帖提出。
  查看全部
   这里整理了集成环信的常见问题和一些功能的实现思路,希望能帮助到大家。感谢热心的开发者贡献,大家在观看过程中有不明白的地方欢迎直接跟帖咨询。
 
ios篇

 
Android篇

昵称头像篇

 
直播篇
  1. 一言不合你就搞个直播APP

 
客服集成
  1. IM-SDK和客服SDK并存开发指南—Android篇
  2. IM-SDK和客服SDK并存开发指南—iOS篇

 
开源项目

 
持续更新ing...小伙伴们还有什么想知道欢迎跟帖提出。
 
0
评论

微信后台基于时间序的海量数据冷热分级架构设计实践 架构 微信

beyond 发表了文章 • 810 次浏览 • 2017-06-27 16:37 • 来自相关话题

   微信的后台数据存储随着微信产品特性的演进,经历了数次的架构改造,才形成如今成熟的大规模分布式存储系统,有条不紊的管理着由数千台异构机型组成的机器集群,得以支撑每天千万亿级的访问、键值以及 PB 级的数据。

   作为以手机为平台的移动社交应用,微信内大部分业务生成的数据是有共性可言的:数据键值带有时间戳信息,并且单用户数据随着时间在不断的生成。我们将这类数据称为基于时间序的数据。比如朋友圈中的发表,或者移动支付的账单流水等业务生成的数据都满足这样的特征。基于时间序的数据都天然带有冷热分明属性――这是由手机的物理特性决定的,它的尺寸有限的屏幕所展示的数据只能分屏,通过手指的滑动,平滑而又连续的沿时间轴依次访问――通常是由最新生成的数据,慢慢回溯到较早前的数据。同时朋友圈等业务都是信息读扩散的应用场景,这就意味着它们生成的后台数据具有读多写少的鲜明特征。
在微信的实际应用场景中,这类数据的主要特点包括:数据量大、访问量大、重要程度高等。这些特点在现网的实际运营过程中,给我们带来了非常大的挑战,主要包括:数据量大,需求的存储容量高――基于时间序的数据通常不会删除,而是随着时间不断积累,数据量达到 PB 级别,相应需要的存储空间也与日俱增;访问量大,节日效应明显――基于时间序的数据往往是热点业务生成的数据,它们的访问量居高不下,基本维持在每分钟数十亿次的级别。尤其是在节日期间,瞬发访问量更可达平日的三至五倍;重要性高,用户感知明显,数据一旦丢失,导致用户不能正常使用产品,并因此而转化成的投诉率高。

   通过堆机器来横向扩展存储自然可以应对如上的各种挑战,然而在成本预算紧张的前提下,机器数目是有限的。在这种情况下,基于时间序的海量数据的冷热分级架构便应运而生。该架构正是为了应对后台日益膨胀的这类数据,本着充分利用机器资源,发挥各种硬件介质特长的原则,结合数据的冷热分明、读多写少的访问特征而开发和设计出来的。它基于数据分层的理念,根据不同时间段的数据在访问热度和数据量上的差异,定制不同的服务策略,在纵向上扩展存储的边界。横向扩展存储是易于理解的,通过向原集群中增加相同类型的机器――其中必然涉及到一轮历史数据的迁移――最终新旧机器负载均衡,彼此之间并无差异的对外提供服务。在这种方案下,数据横向流动,系统一视同仁的对待,显然并无因地制宜思想的容身之所。而纵向扩展存储的架构便提供了这样一种思路:

   对热点数据,数据量少,但承担的访问流量大,我们当然是希望它们能常驻内存,因此系统提供了有强一致保证的内存层,在应对突发流量时,也可在不涉及历史数据迁移的前提下,单独、动态的快速扩展内存层。

   对历史数据,数据存量大,但承担的访问量非常有限,我们当然是不希望用昂贵的固态硬盘来存储它们,因此,系统提供了廉价的机械盘层,并且有一套透明的冷数据剥离和批量下沉的流程,将存储层中历史数据源源不断的抽离到机械盘层。

   通过这样的一种纵向分层、单独扩展的思路,即为我们系统提供了极大的灵活性,解决了节日期间存储层面临的内存瓶颈,以从长远的角度为我们缓解了成本压力,解决了存储层面临的磁盘容量瓶颈。

   当然一套成功的大型分布式系统仅有这些是不够的,还必须包括数据多副本复制策略以及分区算法等,也要有能应对复杂的现网运营环境的能力。我们结合各层的服务特点,制订了相对应的数据强一致算法,如内存层通过版本号控制来保证与存储层的完全一致,存储层通过 Paxos Group 实现多副本容灾,而机械盘层则通过串行写来保证。我们同时也实现了自己的去中心化的数据路由算法,确保了数据和流量的均匀分布,并且保证这种特性在横向扩展后依然成立。

   通过如上工作的努力,环环相扣,我们的基于时间序的海量数据的冷热分层架构成功的应对了 PB 级数据、千亿级访问以及万亿级键值带来的挑战。

系统设计
数据模型
本文提及的海量数据的冷热分级架构是专门服务于基于时间序的数据,它们主要特征为:

a). 数据键值带有时间戳信息 ;

b). 单用户数据随着时间在不断的生成。

   我们设计的架构强依赖于特性 a),各个环节基本上是依赖于键值中的时间戳来分发数据或者进行数据排序的。至于键值中的时间戳如何生成、全局是否维持统一时间、如何维持等则不在本文的讨论范围,通常这由前端的业务特性以及后台的时间服务器策略决定的。

   而特性 b) 则保证了本架构的必要性、实用性。如果数据规模有限,以用户的账户信息举例,它就像我们日常生活中的户口本,它只有一份,对单用户而言不会新增。则我们通常用固定的机器集群存储就可以,并且鲜有变更。而我们要处理的是用户的日记本、或者记账簿,它们每天都在不断生成新数据。

我们以现网某个集群的实例情况举例,说明下此类业务数据有如下的特点:

1.、数据量大,PB 级数据,万亿级键值,并且在源源不断的生成中,然而新生成的数据相较于历史存量数据占比小。下图展示了该集群数据在各时间段的一个占比情况。




2、访问量大,峰值可达每分钟数十亿次访问,尤其是在节日期间,用户高涨的热情更可以转化成平日三至五倍的访问量。同时具有冷热分明、读多写少 (读写比例甚至可达 100:1) 的访问特征,比如节日期间倍增的访问通常是对节日期间生成的新增数据的访问。下图展示了该集群访问在各时间段的一个占比情况。




3、数据安全性要求高,这类数据通常是用户感知敏感数据,一旦丢失,转化成的用户投诉率高。




存储层





数据强一致性保证
 
业务要求系统必须保证在数据的多份副本之间保持强一致性。――这是一个历久弥新的挑战。我们将分内存层、存储层、机械硬盘层分别来考虑数据的强一致性维持。
 
强一致缓存
 
正如前文描述,内存层作为一种强一致性分布式缓存,它完全是向存储层对齐的,自身无法判别数据有效性,本身多副本之间也没有交互的必要。它对前端而言是只读的,所有的写请求并不通过它,它只能算是存储层中数据的一个视图。所以它对前端数据有效性的承诺完全是依赖于存储层的正确性的。
 
Paxos Group
 
我们基于 Paxos Group 实现了存储层的数据一致性,通过采用无租约的方式,使得系统在保证强一致性的前提下达到了最大的可用性。Paxos 算法是由 Lesile Lamport 在论文中首提的,它唯一的作用是在多个参与者之间唯一的确定一个常量值。――这点同分布式存储没有直接关联的。我们在 Paxos 算法的基础上,设计出基于消息驱动的 Paxos Log 组件――每一条操作日志都要 Paxos 算法来确定,再进一步实现了基于 Paxos Log 的强一致性读写。

Paxos Group 因为采用了无主模型,组内所有机器在任一时刻都处于相同的地位。Paxos 算法本质是个多副本同步写算法,当且仅当系统中的多数派都接受相同值后,才会返回写成功。因此任意单一节点的失效,都不会出现系统的不可用。

强一致性写协议的主要问题来源于 Paxos 算法本身,因为要确保数据被系统内的多数派接受,需要进行多阶段的交互。我们采用如下的方法,解决了 paxos 算法写过程中出现的问题:基于 fast accept 协议优化了写算法,降低了写盘量以及协议消息发送、接收次数,最终实现了写耗时和失败的降低;基于随机避让、限制单次 Paxos 写触发 Prepare 的次数等方法,解决了 Paxos 中的活锁问题。

强一致性读协议本身和 Paxos 算法并没有太大的关系,只要确认多副本之间的多数派,即可获取到最新的数据。我们通过广播的方式获取到集群中多数机器(包含自身)的 paxos log 的状态,然后判断本机数据的有效性。

当系统中的单机节点失效,数据完全丢失的时候――这种情况是可以算是 Paxos 算法的盲区,因为该算法基于所有的参与者都不会违背自己曾经的承诺,即拜占庭失败而导致的数据不一致。――而这种情况在现网运营中可谓是常态,因此,我们引入了 Learner Only 模式。在该模式下故障机只接收已提交的数据,而不参与 Paxos 协议的写过程,意即不会因数据丢失而违背任何承诺。然后通过异步 catch up 和全量数据校验快速从其它副本中恢复数据。

为了防止多节点同时失效,我们将数据的多副本分布在不同园区的机器上。园区是同一个城市不同数据中心的概念。如此,我们的结构足以应对单数据中心完全隔离级别的灾难。
 
串行写入
 
因为对客户端透明,冷数据下沉流程作为机械硬盘层的唯一写者,则该层的数据一致性是易于实现的。我们通过三副本串行写入、全部提交才算成功的方式来实现了多副本之间的数据一致性。

作为补充,冷数据集群为数据块增加了 CRC 校验和一致性恢复队列,当单机数据不可用 (丢失或者损坏) 时,首先客户端会跳转到其它备份中读 (三机同时对外提供读服务),一致性恢复队列会异步的从其它备份数据块中恢复本机数据。

因为采用了 No Raid 方式组织的盘组,并且同组机器间盘级别数据文件一致,在单盘故障引发数据丢失时,只要从其它机器相同序盘中传输数据文件即可。

数据分区
 
静态映射表
 
数据分区的主要目的是为了确保同层机器间的负载均衡,并且当机器规模发生变化后,在最终仍然可以达到负载均衡的一种状态。

经典的一致性哈希算法的初衷是为了健壮分布式缓存,基于运行时动态的计算哈希值和虚拟节点来进行寻址。数据存储与分布式缓存的不同在于,存储必须保证数据映射的单调性,而缓存则无此要求,所以经典的一致性哈希通常会使用机器 IP 等作为参数来进行哈希,这样造成的结果一方面是数据的落点时而发生改变,一方面是负载通常不均衡。因此我们改造了此算法。

我们通过预计算虚拟节点随机数的方法,生成了割环点同实体机器之间的映射表。该映射表最多可支持一千组的集群规模,满足在任意组数情况下,实体机器间割段长度维持差异在 2% 以内;并且增加任意组数 (总组数上限不超过一千组),变动后的实体机器间的割段长度依然维持差异在 2% 以内。我们将此映射表硬编码,在运行时避免了计算的过程,数据根据键值哈希值寻址时,只要经过一次二分查找即可获取到对应的实体机器的编号。我们在内存层、存储层以及机械硬盘层都采用了这个映射表,保证了数据在各层路由算法的一致。在工程实现方面,我们可以合理使用这个特性来批量合并请求,以降低资源消耗,这在稍后的章节会有详细描述。
 
组内均衡
 
组是数据分区的独立单元,是虚拟节点对应的实体单位。组之间是互相独立的。每组由多台物理机器组成,这是 Paxos Group 生效的基本单位。一份数据包括的多份副本分别散落在组内的各台机器上。为了在组内机器上保证负载均衡,我们同样设计了一套算法,规定了数据副本之间的访问优先级,前端会依优先级逐一的请求数据,只要成功获取,即中断这个过程。然后我们再将副本按优先级均匀的散落在组内机器上,如此即可实现组内负载的均衡。
 
数据迁移
 
静态映射表是非常灵活的,在不达到组数上限的情况下,可以任意的增加一组或者多组机器。当然这个过程中一些数据的路由映射发生了改变,则就涉及到了历史数据的挪腾。为了在挪腾的过程中不影响服务,保证数据依然可读可写,我们开发出了对前端透明的,基于迁移标志位,通过数据双写和异步挪数据的方式实现的安全的、可回退的数据迁移流程。
 
最小不变块
 
存储层和机械硬盘层通过冷数据链接耦合在了一起。因为两层使用了相同的映射表,那么当存储层因扩容而发生迁移时,那么冷数据链接无疑也要重新寻址,进行一轮重新定位。如果我们以单键值为粒度记录冷数据链接和进行冷数据下沉,那么在万亿键值的语境下,效率无疑是低下。因此我们设计了最小不变块的算法,通过两阶段哈希,使用中间的哈希桶聚集数据,将数据键值和冷数据存储层的机器路由隔离开来。通过该算法,我们可以实现:批量的转存冷数据、热数据存储层批量的以块 (block) 为单位记录冷数据链接、当热数据存储层发生扩容时,块 (block) 内的数据不因扩容被打散掉,而可以整体的迁移到新目标机上。
 
工程实现
 
糟糕的工程实现可以毁掉一个完美的系统设计,因此,如何在工程实现的过程中,通过技术的手段,提升系统的表现,同样值得重视。
 
高效缓存
 
内存层的设计严重依赖存储层数据版本号的高效获取,那自然是版本号请求全落在内存中就可以了。因此,针对这种情况我们为定长的版本号设计了一套极简的、轻量的、行之有效的缓存――内存容量不足以支撑版本号全缓存。




它的数据结构只是一个二维数组,一维用来构建 hash 链,一维用来实现 LRU 链。每次读或者写都需要通过数组内数据的挪动,来进行更新。如此一来,我们就通过千万级数目的 LRU 链群,实现了缓存整体的 LRU 淘汰。它具有定长,可共享内存搭载,进程重启不丢失、内存使用率高等优点。
 
批量操作
 
对系统服务器而言,前端访问过来的某个请求,其对应的逻辑操作都是串行的,我们自然可以梳理这个串行流程中的 CPU 消耗点进行优化。然而当主要的瓶颈被逐渐的消灭掉后,CPU 消耗点变得分散,优化效果就变得微乎其微了。因此,我们只能寻找其它突破点。

我们发现在存储引擎、一致性协议算法的实现流程中,逻辑操作步骤多,涉及到网络交互,硬盘读写等过程。因此,我们决定合并不同请求中的相同步骤,实现批量化操作,极大的优化了 CPU 消耗。

合并的代价即是耗时略有增加,我们通过快慢分离,只针对热点数据请求中的逻辑操作进行合并,去掉了耗时中的不稳定因子,减少了耗时抖动。
 
请求合并
 
既然单机的逻辑操作性能已经得到了极大的提升,那么前后端的网络交互阶段,包括接入层的打包解包、协议处理等环节,成为了资源的主要消耗点。参考批量操作的经验,我们同样使用批量化的技术来优化性能――即将后台访问过来的单条请求 (Get) 在内存层聚合成一次批量请求 (Batch Get)。
 
路由收敛
 
因为每个数据都是根据键值单独进行路由的,如果要进行请求合并,我们就必须确保同一个批量请求内的数据,都会寻址到相同的 Paxos Group 上。因此,我们必须在内存层将落到同一台存储机器上的 Get 请求聚合起来。我们首先在内存层和存储层采用了相同的路由算法,然后将内存层的组数同存储层的组数进行对齐,来完成了这一目标。






相关工作
 
在设计的阶段,我们充分的调研了业界的各类方案,大到系统的整体架构,小到具体的技术点。各种方案自有应用场景、各有千秋,不能单纯以好坏区别,我们同样基于自己的业务场景,谨慎的选择合适的方案,或者弃而不用。在此尽量叙述。

处理 SNS 类业务生成的数据,业界有多种的冷热分离架构可以参考。我们以 Facebook 的 Cold Storage 系统举例而言,它也是基于冷热分层的想法,设计出了服务它们照片业务数据的存储方案。不同的是它采用了软硬件结合的方法,一方面定制专门的服务器(包括硬盘、电源等)和数据中心,一方面降低冷数据的备份数、增加纠删码等手段。

然而它们的经验我们是无法彻底套用的,主要两种原因:我们可使用的机器机型是固定的,不存在自己定制硬件的条件。同时它处理的是照片这种大 value 的数据。而我们基本上是文本这种类型的小 value 数据。从前文提及的 TB 访问量角度来看,它们处理的数据是容量瓶颈的,而我们处理的是 IO 瓶颈的,可以算是不太冷的冷数据带来的挑战。所以,我们只能实现自己的冷数据管理策略。

同样,业界有诸多关于如何实现数据一致性的方案。包括我们微信自研的 Quorum 协议,它是一种 NWR 协议,采用异步同步的方式实现数据多副本。即然是异步同步,那在多副本达到最终一致,必然存在一个时间差,那么在单机出现离线的情况下,就会有一定概率导致数据的不可用。而我们追求的是在单点故障下,所有的数据都保证强可用性。

因此,我们采用了无主的去中心化的 Paxos Group 实现了这一目标,其中非租约是 PaxosStore 架构的一个创新亮点。在故障时通常系统是抖动的,会有时断时续的状况,常见的租约做法在这种场景下容易出现反复切换主机而导致长期不可用,而 PaxosStore 的非租约结构能够轻松应对,始终提供良好的服务。PaxosStore 核心代码正在整理开源当中,预计四季度会正式发布,同时该项目的底层框架也基于我们已开源的协程库 github.com/libco。
 
转自“计算机与网络安全”,作者杨平安 查看全部
   微信的后台数据存储随着微信产品特性的演进,经历了数次的架构改造,才形成如今成熟的大规模分布式存储系统,有条不紊的管理着由数千台异构机型组成的机器集群,得以支撑每天千万亿级的访问、键值以及 PB 级的数据。

   作为以手机为平台的移动社交应用,微信内大部分业务生成的数据是有共性可言的:数据键值带有时间戳信息,并且单用户数据随着时间在不断的生成。我们将这类数据称为基于时间序的数据。比如朋友圈中的发表,或者移动支付的账单流水等业务生成的数据都满足这样的特征。基于时间序的数据都天然带有冷热分明属性――这是由手机的物理特性决定的,它的尺寸有限的屏幕所展示的数据只能分屏,通过手指的滑动,平滑而又连续的沿时间轴依次访问――通常是由最新生成的数据,慢慢回溯到较早前的数据。同时朋友圈等业务都是信息读扩散的应用场景,这就意味着它们生成的后台数据具有读多写少的鲜明特征。
  1. 在微信的实际应用场景中,这类数据的主要特点包括:数据量大、访问量大、重要程度高等。这些特点在现网的实际运营过程中,给我们带来了非常大的挑战,主要包括:
  2. 数据量大,需求的存储容量高――基于时间序的数据通常不会删除,而是随着时间不断积累,数据量达到 PB 级别,相应需要的存储空间也与日俱增;
  3. 访问量大,节日效应明显――基于时间序的数据往往是热点业务生成的数据,它们的访问量居高不下,基本维持在每分钟数十亿次的级别。尤其是在节日期间,瞬发访问量更可达平日的三至五倍;
  4. 重要性高,用户感知明显,数据一旦丢失,导致用户不能正常使用产品,并因此而转化成的投诉率高。


   通过堆机器来横向扩展存储自然可以应对如上的各种挑战,然而在成本预算紧张的前提下,机器数目是有限的。在这种情况下,基于时间序的海量数据的冷热分级架构便应运而生。该架构正是为了应对后台日益膨胀的这类数据,本着充分利用机器资源,发挥各种硬件介质特长的原则,结合数据的冷热分明、读多写少的访问特征而开发和设计出来的。它基于数据分层的理念,根据不同时间段的数据在访问热度和数据量上的差异,定制不同的服务策略,在纵向上扩展存储的边界。横向扩展存储是易于理解的,通过向原集群中增加相同类型的机器――其中必然涉及到一轮历史数据的迁移――最终新旧机器负载均衡,彼此之间并无差异的对外提供服务。在这种方案下,数据横向流动,系统一视同仁的对待,显然并无因地制宜思想的容身之所。而纵向扩展存储的架构便提供了这样一种思路:

   对热点数据,数据量少,但承担的访问流量大,我们当然是希望它们能常驻内存,因此系统提供了有强一致保证的内存层,在应对突发流量时,也可在不涉及历史数据迁移的前提下,单独、动态的快速扩展内存层。

   对历史数据,数据存量大,但承担的访问量非常有限,我们当然是不希望用昂贵的固态硬盘来存储它们,因此,系统提供了廉价的机械盘层,并且有一套透明的冷数据剥离和批量下沉的流程,将存储层中历史数据源源不断的抽离到机械盘层。

   通过这样的一种纵向分层、单独扩展的思路,即为我们系统提供了极大的灵活性,解决了节日期间存储层面临的内存瓶颈,以从长远的角度为我们缓解了成本压力,解决了存储层面临的磁盘容量瓶颈。

   当然一套成功的大型分布式系统仅有这些是不够的,还必须包括数据多副本复制策略以及分区算法等,也要有能应对复杂的现网运营环境的能力。我们结合各层的服务特点,制订了相对应的数据强一致算法,如内存层通过版本号控制来保证与存储层的完全一致,存储层通过 Paxos Group 实现多副本容灾,而机械盘层则通过串行写来保证。我们同时也实现了自己的去中心化的数据路由算法,确保了数据和流量的均匀分布,并且保证这种特性在横向扩展后依然成立。

   通过如上工作的努力,环环相扣,我们的基于时间序的海量数据的冷热分层架构成功的应对了 PB 级数据、千亿级访问以及万亿级键值带来的挑战。

系统设计
数据模型
本文提及的海量数据的冷热分级架构是专门服务于基于时间序的数据,它们主要特征为:

a). 数据键值带有时间戳信息 ;

b). 单用户数据随着时间在不断的生成。

   我们设计的架构强依赖于特性 a),各个环节基本上是依赖于键值中的时间戳来分发数据或者进行数据排序的。至于键值中的时间戳如何生成、全局是否维持统一时间、如何维持等则不在本文的讨论范围,通常这由前端的业务特性以及后台的时间服务器策略决定的。

   而特性 b) 则保证了本架构的必要性、实用性。如果数据规模有限,以用户的账户信息举例,它就像我们日常生活中的户口本,它只有一份,对单用户而言不会新增。则我们通常用固定的机器集群存储就可以,并且鲜有变更。而我们要处理的是用户的日记本、或者记账簿,它们每天都在不断生成新数据。

我们以现网某个集群的实例情况举例,说明下此类业务数据有如下的特点:

1.、数据量大,PB 级数据,万亿级键值,并且在源源不断的生成中,然而新生成的数据相较于历史存量数据占比小。下图展示了该集群数据在各时间段的一个占比情况。
001.jpg

2、访问量大,峰值可达每分钟数十亿次访问,尤其是在节日期间,用户高涨的热情更可以转化成平日三至五倍的访问量。同时具有冷热分明、读多写少 (读写比例甚至可达 100:1) 的访问特征,比如节日期间倍增的访问通常是对节日期间生成的新增数据的访问。下图展示了该集群访问在各时间段的一个占比情况。
002.jpg

3、数据安全性要求高,这类数据通常是用户感知敏感数据,一旦丢失,转化成的用户投诉率高。
003.jpg

存储层

004.jpg

数据强一致性保证
 
业务要求系统必须保证在数据的多份副本之间保持强一致性。――这是一个历久弥新的挑战。我们将分内存层、存储层、机械硬盘层分别来考虑数据的强一致性维持。
 
强一致缓存
 
正如前文描述,内存层作为一种强一致性分布式缓存,它完全是向存储层对齐的,自身无法判别数据有效性,本身多副本之间也没有交互的必要。它对前端而言是只读的,所有的写请求并不通过它,它只能算是存储层中数据的一个视图。所以它对前端数据有效性的承诺完全是依赖于存储层的正确性的。
 
Paxos Group
 
我们基于 Paxos Group 实现了存储层的数据一致性,通过采用无租约的方式,使得系统在保证强一致性的前提下达到了最大的可用性。Paxos 算法是由 Lesile Lamport 在论文中首提的,它唯一的作用是在多个参与者之间唯一的确定一个常量值。――这点同分布式存储没有直接关联的。我们在 Paxos 算法的基础上,设计出基于消息驱动的 Paxos Log 组件――每一条操作日志都要 Paxos 算法来确定,再进一步实现了基于 Paxos Log 的强一致性读写。

Paxos Group 因为采用了无主模型,组内所有机器在任一时刻都处于相同的地位。Paxos 算法本质是个多副本同步写算法,当且仅当系统中的多数派都接受相同值后,才会返回写成功。因此任意单一节点的失效,都不会出现系统的不可用。

强一致性写协议的主要问题来源于 Paxos 算法本身,因为要确保数据被系统内的多数派接受,需要进行多阶段的交互。我们采用如下的方法,解决了 paxos 算法写过程中出现的问题:基于 fast accept 协议优化了写算法,降低了写盘量以及协议消息发送、接收次数,最终实现了写耗时和失败的降低;基于随机避让、限制单次 Paxos 写触发 Prepare 的次数等方法,解决了 Paxos 中的活锁问题。

强一致性读协议本身和 Paxos 算法并没有太大的关系,只要确认多副本之间的多数派,即可获取到最新的数据。我们通过广播的方式获取到集群中多数机器(包含自身)的 paxos log 的状态,然后判断本机数据的有效性。

当系统中的单机节点失效,数据完全丢失的时候――这种情况是可以算是 Paxos 算法的盲区,因为该算法基于所有的参与者都不会违背自己曾经的承诺,即拜占庭失败而导致的数据不一致。――而这种情况在现网运营中可谓是常态,因此,我们引入了 Learner Only 模式。在该模式下故障机只接收已提交的数据,而不参与 Paxos 协议的写过程,意即不会因数据丢失而违背任何承诺。然后通过异步 catch up 和全量数据校验快速从其它副本中恢复数据。

为了防止多节点同时失效,我们将数据的多副本分布在不同园区的机器上。园区是同一个城市不同数据中心的概念。如此,我们的结构足以应对单数据中心完全隔离级别的灾难。
 
串行写入
 
因为对客户端透明,冷数据下沉流程作为机械硬盘层的唯一写者,则该层的数据一致性是易于实现的。我们通过三副本串行写入、全部提交才算成功的方式来实现了多副本之间的数据一致性。

作为补充,冷数据集群为数据块增加了 CRC 校验和一致性恢复队列,当单机数据不可用 (丢失或者损坏) 时,首先客户端会跳转到其它备份中读 (三机同时对外提供读服务),一致性恢复队列会异步的从其它备份数据块中恢复本机数据。

因为采用了 No Raid 方式组织的盘组,并且同组机器间盘级别数据文件一致,在单盘故障引发数据丢失时,只要从其它机器相同序盘中传输数据文件即可。

数据分区
 
静态映射表
 
数据分区的主要目的是为了确保同层机器间的负载均衡,并且当机器规模发生变化后,在最终仍然可以达到负载均衡的一种状态。

经典的一致性哈希算法的初衷是为了健壮分布式缓存,基于运行时动态的计算哈希值和虚拟节点来进行寻址。数据存储与分布式缓存的不同在于,存储必须保证数据映射的单调性,而缓存则无此要求,所以经典的一致性哈希通常会使用机器 IP 等作为参数来进行哈希,这样造成的结果一方面是数据的落点时而发生改变,一方面是负载通常不均衡。因此我们改造了此算法。

我们通过预计算虚拟节点随机数的方法,生成了割环点同实体机器之间的映射表。该映射表最多可支持一千组的集群规模,满足在任意组数情况下,实体机器间割段长度维持差异在 2% 以内;并且增加任意组数 (总组数上限不超过一千组),变动后的实体机器间的割段长度依然维持差异在 2% 以内。我们将此映射表硬编码,在运行时避免了计算的过程,数据根据键值哈希值寻址时,只要经过一次二分查找即可获取到对应的实体机器的编号。我们在内存层、存储层以及机械硬盘层都采用了这个映射表,保证了数据在各层路由算法的一致。在工程实现方面,我们可以合理使用这个特性来批量合并请求,以降低资源消耗,这在稍后的章节会有详细描述。
 
组内均衡
 
组是数据分区的独立单元,是虚拟节点对应的实体单位。组之间是互相独立的。每组由多台物理机器组成,这是 Paxos Group 生效的基本单位。一份数据包括的多份副本分别散落在组内的各台机器上。为了在组内机器上保证负载均衡,我们同样设计了一套算法,规定了数据副本之间的访问优先级,前端会依优先级逐一的请求数据,只要成功获取,即中断这个过程。然后我们再将副本按优先级均匀的散落在组内机器上,如此即可实现组内负载的均衡。
 
数据迁移
 
静态映射表是非常灵活的,在不达到组数上限的情况下,可以任意的增加一组或者多组机器。当然这个过程中一些数据的路由映射发生了改变,则就涉及到了历史数据的挪腾。为了在挪腾的过程中不影响服务,保证数据依然可读可写,我们开发出了对前端透明的,基于迁移标志位,通过数据双写和异步挪数据的方式实现的安全的、可回退的数据迁移流程。
 
最小不变块
 
存储层和机械硬盘层通过冷数据链接耦合在了一起。因为两层使用了相同的映射表,那么当存储层因扩容而发生迁移时,那么冷数据链接无疑也要重新寻址,进行一轮重新定位。如果我们以单键值为粒度记录冷数据链接和进行冷数据下沉,那么在万亿键值的语境下,效率无疑是低下。因此我们设计了最小不变块的算法,通过两阶段哈希,使用中间的哈希桶聚集数据,将数据键值和冷数据存储层的机器路由隔离开来。通过该算法,我们可以实现:批量的转存冷数据、热数据存储层批量的以块 (block) 为单位记录冷数据链接、当热数据存储层发生扩容时,块 (block) 内的数据不因扩容被打散掉,而可以整体的迁移到新目标机上。
 
工程实现
 
糟糕的工程实现可以毁掉一个完美的系统设计,因此,如何在工程实现的过程中,通过技术的手段,提升系统的表现,同样值得重视。
 
高效缓存
 
内存层的设计严重依赖存储层数据版本号的高效获取,那自然是版本号请求全落在内存中就可以了。因此,针对这种情况我们为定长的版本号设计了一套极简的、轻量的、行之有效的缓存――内存容量不足以支撑版本号全缓存。
005.jpg

它的数据结构只是一个二维数组,一维用来构建 hash 链,一维用来实现 LRU 链。每次读或者写都需要通过数组内数据的挪动,来进行更新。如此一来,我们就通过千万级数目的 LRU 链群,实现了缓存整体的 LRU 淘汰。它具有定长,可共享内存搭载,进程重启不丢失、内存使用率高等优点。
 
批量操作
 
对系统服务器而言,前端访问过来的某个请求,其对应的逻辑操作都是串行的,我们自然可以梳理这个串行流程中的 CPU 消耗点进行优化。然而当主要的瓶颈被逐渐的消灭掉后,CPU 消耗点变得分散,优化效果就变得微乎其微了。因此,我们只能寻找其它突破点。

我们发现在存储引擎、一致性协议算法的实现流程中,逻辑操作步骤多,涉及到网络交互,硬盘读写等过程。因此,我们决定合并不同请求中的相同步骤,实现批量化操作,极大的优化了 CPU 消耗。

合并的代价即是耗时略有增加,我们通过快慢分离,只针对热点数据请求中的逻辑操作进行合并,去掉了耗时中的不稳定因子,减少了耗时抖动。
 
请求合并
 
既然单机的逻辑操作性能已经得到了极大的提升,那么前后端的网络交互阶段,包括接入层的打包解包、协议处理等环节,成为了资源的主要消耗点。参考批量操作的经验,我们同样使用批量化的技术来优化性能――即将后台访问过来的单条请求 (Get) 在内存层聚合成一次批量请求 (Batch Get)。
 
路由收敛
 
因为每个数据都是根据键值单独进行路由的,如果要进行请求合并,我们就必须确保同一个批量请求内的数据,都会寻址到相同的 Paxos Group 上。因此,我们必须在内存层将落到同一台存储机器上的 Get 请求聚合起来。我们首先在内存层和存储层采用了相同的路由算法,然后将内存层的组数同存储层的组数进行对齐,来完成了这一目标。

006.jpg


相关工作
 
在设计的阶段,我们充分的调研了业界的各类方案,大到系统的整体架构,小到具体的技术点。各种方案自有应用场景、各有千秋,不能单纯以好坏区别,我们同样基于自己的业务场景,谨慎的选择合适的方案,或者弃而不用。在此尽量叙述。

处理 SNS 类业务生成的数据,业界有多种的冷热分离架构可以参考。我们以 Facebook 的 Cold Storage 系统举例而言,它也是基于冷热分层的想法,设计出了服务它们照片业务数据的存储方案。不同的是它采用了软硬件结合的方法,一方面定制专门的服务器(包括硬盘、电源等)和数据中心,一方面降低冷数据的备份数、增加纠删码等手段。

然而它们的经验我们是无法彻底套用的,主要两种原因:我们可使用的机器机型是固定的,不存在自己定制硬件的条件。同时它处理的是照片这种大 value 的数据。而我们基本上是文本这种类型的小 value 数据。从前文提及的 TB 访问量角度来看,它们处理的数据是容量瓶颈的,而我们处理的是 IO 瓶颈的,可以算是不太冷的冷数据带来的挑战。所以,我们只能实现自己的冷数据管理策略。

同样,业界有诸多关于如何实现数据一致性的方案。包括我们微信自研的 Quorum 协议,它是一种 NWR 协议,采用异步同步的方式实现数据多副本。即然是异步同步,那在多副本达到最终一致,必然存在一个时间差,那么在单机出现离线的情况下,就会有一定概率导致数据的不可用。而我们追求的是在单点故障下,所有的数据都保证强可用性。

因此,我们采用了无主的去中心化的 Paxos Group 实现了这一目标,其中非租约是 PaxosStore 架构的一个创新亮点。在故障时通常系统是抖动的,会有时断时续的状况,常见的租约做法在这种场景下容易出现反复切换主机而导致长期不可用,而 PaxosStore 的非租约结构能够轻松应对,始终提供良好的服务。PaxosStore 核心代码正在整理开源当中,预计四季度会正式发布,同时该项目的底层框架也基于我们已开源的协程库 github.com/libco。
 
转自“计算机与网络安全”,作者杨平安
0
评论

技术选型最怕的是什么? 一乐 技术选型 架构 环信

beyond 发表了文章 • 2619 次浏览 • 2017-02-07 16:41 • 来自相关话题

昨天聊聊架构发布了一篇关于技术选型的文章,文章作者介绍了目前流行的技术选型方式,比如有微博驱动、技术会议驱动、嗓门驱动、领导驱动.....不少读者都表示深有体会,并在评论区贴出了自己的经历。今天再推荐一篇由环信首席架构师一乐所撰写的关于技术选型的文章(旧文),希望能帮到各位。另推荐一乐的个人微信一乐来了,id是yilecoming,欢迎关注。这也许是我上半年最大的欠账,在去普吉的飞机上突发无聊,想想还了这债吧。

去年的时候,我们使用Cassandra出了一次问题,定位加修复用了一晚上。当我把经历发出来的时候,收到了下面一段话:

“一个开源产品,连官方文档都没看完大半,然后匆匆忙忙上生产环境,出了问题团团转。若是不能掌控就先不要玩,说回这Cassandra的例子,在对它不了解的情况下,仅通过Google就能解决问题,不正说明它不难掌握有大量资料可查吗,实在不行还能翻代码。”

我现在都不知道这位神仙从哪里看到的匆匆忙忙上和团团转,当时我还是忍了,因为实在太忙,口水又没那么多。当然我思考了很多,这就是你现在看到的文章。我相信它会有一些价值,毕竟有些事情有的人你不告诉他,他永远不可能知道。比如个体认知的局限,比如口无遮拦的损失,比如做事之人才会有的思考角度。

本文讲的是技术选型。

大多数技术都存在选型问题,因为技术的发展已经让一件事情可以有多种解决方案,选型问题就自然出现。前段时间也有人说过语言选型,这里举的例子是在组件、框架、服务的范畴。其中有相通之处,各位可以自行领会。
 
选型最怕什么
 
怕失败么?那肯定的。你的服务崩溃,用户愤而投诉,客户电话打到老板那里,明天你要洗干净到办公室去一趟(笑...)。而所有对失败的无法容忍,最终都会变成一句话,为什么你要选这个型?

你总要回答这个问题,所以选型一怕随意,公鸡头母鸡头,选上哪头是哪头;二怕凭感觉,某某已经在用听起来还不错。你需要真正的思考,而且尽可能的全面。我下文会详细讲解,但这还不是最怕的。

最怕的是什么?看看本文开头引用的那句话,你体会一下。

嗯,最怕的是喷子。怕任意总结,如果再加上一些诋毁,一次选型失败足以让人心碎一万次。

失败不可怕,可怕的是没有总结,因为没有总结就没有提高。而比没有总结更可怕的是乱总结。

为了方便理解,我再帮你换个角度。你天天在河边走,一次不小心湿了鞋。如果是本文说的这种人,那肯定要说:

一条公共的河,你连旱季旺季都没搞清楚,就匆匆忙忙跑过来散步,湿了鞋还到处讲。若是脚不行就别在这玩,说回这条河,湿了鞋就能爬上来,不正说明他水不深么。

这种人实在不算少见。他说的每一句话都有一点道理,但都跟事情的本质毫无关系,每一句话又都掺加了嘲讽,来体现那无处安放的莫名优越感。而所有的这些,对于解决问题和后续提高通常毫无帮助。

想想也真遗憾,人生本是如此美好,有的人却硬生生地活成了奇葩。
 
选型需要什么
 
言归正传,我认为有三点不可或缺:分析、实验和胆量。
 
 分析
 
分析主要有定性分析和定量分析。实际操作中,前者主要针对的是模型维度的估计,用来考虑一个组件是否有可能达到它宣称的目的,后者主要用来验证,用来确认它是否在真的做到了。

比如在语言选型时,你要考虑它的范型、内存模型和并发设计;数据库选型时你要考虑存储模型、支撑量级、成本开销;开源项目要考虑它的社区发展、文档完善程度;如果是库或者中间件,还要考虑他的易用性、灵活性以及可替代性,等等。

需要说明的一点是,我个人并不觉得阅读全部源码或者文档这种事情是必须的,这不局限在OS、VM层面。不仅因为这样的事情会耗费过多精力,而且受制于代码以及文档质量,就算真正阅读完毕也未必意味着完全领会。

这些都是定性的,而定性的东西就有可能存在理解偏差。一个库可以完成工作,并不代表它在高并发压力下依然表现正常;一个语言做到了自动管理内存,并不代表他能做得很好没有副作用;一件事情设计者觉得达到了目标并不代表能够满足使用者期望。因此我们还需要量化分析,也就是一直口口相传的,用数据说话。

量化分析需要你构建或使用现成的工具和数据集,对服务进行特定场景下的分析。通过提高压力、增加容量或者针对性的测试,来验证之前的定性分析是否达到预期,并分析不同技术之间的差异和表现。
 
实验
 
量化分析可以为真正的实验做一些准备和帮助,但是实验要走的明显更远。到了这一步,意味着要在真正的业务场景下进行验证,这跟量化分析中通用性场景有所不同。

在真正的业务中采用需要很多细致和琐碎的工作,除此之外,还要构建自己的测试工具集,这需要非常扎实的业务理解能力和勤奋的工作。而所有这些,你需要在开发环境做一次,在沙箱环境做一次,然后在仿真环境再做一次。

这几步经常被简化,但经验告诉我们,如果你想做一个高可用的系统,你就不应该少走任何一步。

步子大了,容易扯到蛋。 
 
胆量
 
实验做完,剩下的就是上线,但这一步有很多人跨不过去。因为就算做了再多准备,你依然不敢说百分百保证没问题。现实情况是,80%的线上问题都是升级或者上线引起的。

你需要胆量。

这不是说要硬着头皮做,人家都是艺高才胆大。所以为了让胆子大一点,你首先需要考虑降级和开关。从最悲观的角度来重新审视整个方案,如果升级出现问题怎么办,如何才能让出现的问题影响最小化。

而只要弄完了这些,也就只要再记住一句话就行:

你行你上啊!
 
对技术服务的提醒
 
得到认可
 
刚才在胆量里没说的一点。我们经常会看到,一项新技术在公司内久久难以推行,因为业务主管百般阻挠。即使排除利益纠葛,仍然会发现一种发自心底的不信任存在。而这种不信任,又往往来源于对同事工作的不认可。

这个问题原因很多,也许没有通用的解决方案,但我说一个例子。

我们最近开始使用Codis,就是@goroutine 和几个家伙之前搞过的玩意儿。虽然他们最近已经独立开搞像Google Spanner但拥有更高级特性的TiDB(就是太牛了的意思)。由于我对他们比较熟悉和认可,所以在Codis尝试方面也多出很多底气。这种信任并非完全来自于出问题之后的直接电话支持,而是真心觉得活儿好。

反过来,这对很多服务也是一个提醒,特别是云服务。也许只要你得到合作伙伴的认可,或者至少让他们觉得,自己动手不会比你做得更好,你基本也就成功了。

对于大多数理性创业公司来讲,他们还是更愿意把精力放在自己的主要业务上,不会希望所有的服务都自己做,因为这个年代,唯快不破,创业等不起一辈子。 
 
产品意识
 
回到开始那句话,“在对它不了解的情况下,仅通过google就能解决问题,不正说明它不难掌握有大量资料可查吗,实在不行还能翻代码。” 这话有些道理,然而却存在一个问题,这个问题就是:

作为一个使用者,是否有能力解决遇到的问题,与是否有意愿去遇到并解决问题,是两回事。

你有本CPU设计手册,你可以说处理器很简单,但我只想看个电影啊?给你Linux内核的源码,你可以说内核设计不难掌握,但我只想跑个游戏啊?何况他们是否因此就变得不难了,也是值得怀疑的。

这其实反映了技术人的产品意识。

很多技术人员喜欢玩酷的东西,他们愿意去探索新的领域,把不可能的变为可能。但是很多时候,他们做出来的东西却很难使用。

有的库可以增加很多参数,参数之间却有耦合,导致你在采用的时候需要写很多设置代码,而有点库却只需要一行代码;有的服务功能众多,却需要用户学习繁杂的步骤,而有的服务却可以开箱即用;有的服务功能可以实现,却会有很多不稳定甚至崩溃的情况出现,等等。

对于实现的工程师来讲,可能最大的区别在于,你是否考虑从用户的角度审视过自己的东西。即使这个服务也许只是为其他技术人员使用的。

技术人员可以,也应该,让技术人员更幸福。

最后,聊聊架构为大家送上一个关于技术选型的小漫画。其实技术并没有错,错的也许是我们.....




  查看全部

WOE262@[SP29YD2R2}GGSSQ.png
昨天聊聊架构发布了一篇关于技术选型的文章,文章作者介绍了目前流行的技术选型方式,比如有微博驱动、技术会议驱动、嗓门驱动、领导驱动.....不少读者都表示深有体会,并在评论区贴出了自己的经历。今天再推荐一篇由环信首席架构师一乐所撰写的关于技术选型的文章(旧文),希望能帮到各位。另推荐一乐的个人微信一乐来了,id是yilecoming,欢迎关注。
这也许是我上半年最大的欠账,在去普吉的飞机上突发无聊,想想还了这债吧。

去年的时候,我们使用Cassandra出了一次问题,定位加修复用了一晚上。当我把经历发出来的时候,收到了下面一段话:

“一个开源产品,连官方文档都没看完大半,然后匆匆忙忙上生产环境,出了问题团团转。若是不能掌控就先不要玩,说回这Cassandra的例子,在对它不了解的情况下,仅通过Google就能解决问题,不正说明它不难掌握有大量资料可查吗,实在不行还能翻代码。”

我现在都不知道这位神仙从哪里看到的匆匆忙忙上和团团转,当时我还是忍了,因为实在太忙,口水又没那么多。当然我思考了很多,这就是你现在看到的文章。我相信它会有一些价值,毕竟有些事情有的人你不告诉他,他永远不可能知道。比如个体认知的局限,比如口无遮拦的损失,比如做事之人才会有的思考角度。

本文讲的是技术选型。

大多数技术都存在选型问题,因为技术的发展已经让一件事情可以有多种解决方案,选型问题就自然出现。前段时间也有人说过语言选型,这里举的例子是在组件、框架、服务的范畴。其中有相通之处,各位可以自行领会。
 
选型最怕什么
 
怕失败么?那肯定的。你的服务崩溃,用户愤而投诉,客户电话打到老板那里,明天你要洗干净到办公室去一趟(笑...)。而所有对失败的无法容忍,最终都会变成一句话,为什么你要选这个型?

你总要回答这个问题,所以选型一怕随意,公鸡头母鸡头,选上哪头是哪头;二怕凭感觉,某某已经在用听起来还不错。你需要真正的思考,而且尽可能的全面。我下文会详细讲解,但这还不是最怕的。

最怕的是什么?看看本文开头引用的那句话,你体会一下。

嗯,最怕的是喷子。怕任意总结,如果再加上一些诋毁,一次选型失败足以让人心碎一万次。

失败不可怕,可怕的是没有总结,因为没有总结就没有提高。而比没有总结更可怕的是乱总结。

为了方便理解,我再帮你换个角度。你天天在河边走,一次不小心湿了鞋。如果是本文说的这种人,那肯定要说:

一条公共的河,你连旱季旺季都没搞清楚,就匆匆忙忙跑过来散步,湿了鞋还到处讲。若是脚不行就别在这玩,说回这条河,湿了鞋就能爬上来,不正说明他水不深么。

这种人实在不算少见。他说的每一句话都有一点道理,但都跟事情的本质毫无关系,每一句话又都掺加了嘲讽,来体现那无处安放的莫名优越感。而所有的这些,对于解决问题和后续提高通常毫无帮助。

想想也真遗憾,人生本是如此美好,有的人却硬生生地活成了奇葩。
 
选型需要什么
 
言归正传,我认为有三点不可或缺:分析、实验和胆量。
 
  •  分析

 
分析主要有定性分析和定量分析。实际操作中,前者主要针对的是模型维度的估计,用来考虑一个组件是否有可能达到它宣称的目的,后者主要用来验证,用来确认它是否在真的做到了。

比如在语言选型时,你要考虑它的范型、内存模型和并发设计;数据库选型时你要考虑存储模型、支撑量级、成本开销;开源项目要考虑它的社区发展、文档完善程度;如果是库或者中间件,还要考虑他的易用性、灵活性以及可替代性,等等。

需要说明的一点是,我个人并不觉得阅读全部源码或者文档这种事情是必须的,这不局限在OS、VM层面。不仅因为这样的事情会耗费过多精力,而且受制于代码以及文档质量,就算真正阅读完毕也未必意味着完全领会。

这些都是定性的,而定性的东西就有可能存在理解偏差。一个库可以完成工作,并不代表它在高并发压力下依然表现正常;一个语言做到了自动管理内存,并不代表他能做得很好没有副作用;一件事情设计者觉得达到了目标并不代表能够满足使用者期望。因此我们还需要量化分析,也就是一直口口相传的,用数据说话。

量化分析需要你构建或使用现成的工具和数据集,对服务进行特定场景下的分析。通过提高压力、增加容量或者针对性的测试,来验证之前的定性分析是否达到预期,并分析不同技术之间的差异和表现。
 
  • 实验

 
量化分析可以为真正的实验做一些准备和帮助,但是实验要走的明显更远。到了这一步,意味着要在真正的业务场景下进行验证,这跟量化分析中通用性场景有所不同。

在真正的业务中采用需要很多细致和琐碎的工作,除此之外,还要构建自己的测试工具集,这需要非常扎实的业务理解能力和勤奋的工作。而所有这些,你需要在开发环境做一次,在沙箱环境做一次,然后在仿真环境再做一次。

这几步经常被简化,但经验告诉我们,如果你想做一个高可用的系统,你就不应该少走任何一步。

步子大了,容易扯到蛋。 
 
  • 胆量

 
实验做完,剩下的就是上线,但这一步有很多人跨不过去。因为就算做了再多准备,你依然不敢说百分百保证没问题。现实情况是,80%的线上问题都是升级或者上线引起的。

你需要胆量。

这不是说要硬着头皮做,人家都是艺高才胆大。所以为了让胆子大一点,你首先需要考虑降级和开关。从最悲观的角度来重新审视整个方案,如果升级出现问题怎么办,如何才能让出现的问题影响最小化。

而只要弄完了这些,也就只要再记住一句话就行:

你行你上啊!
 
对技术服务的提醒
 
  • 得到认可

 
刚才在胆量里没说的一点。我们经常会看到,一项新技术在公司内久久难以推行,因为业务主管百般阻挠。即使排除利益纠葛,仍然会发现一种发自心底的不信任存在。而这种不信任,又往往来源于对同事工作的不认可。

这个问题原因很多,也许没有通用的解决方案,但我说一个例子。

我们最近开始使用Codis,就是@goroutine 和几个家伙之前搞过的玩意儿。虽然他们最近已经独立开搞像Google Spanner但拥有更高级特性的TiDB(就是太牛了的意思)。由于我对他们比较熟悉和认可,所以在Codis尝试方面也多出很多底气。这种信任并非完全来自于出问题之后的直接电话支持,而是真心觉得活儿好。

反过来,这对很多服务也是一个提醒,特别是云服务。也许只要你得到合作伙伴的认可,或者至少让他们觉得,自己动手不会比你做得更好,你基本也就成功了。

对于大多数理性创业公司来讲,他们还是更愿意把精力放在自己的主要业务上,不会希望所有的服务都自己做,因为这个年代,唯快不破,创业等不起一辈子。 
 
  • 产品意识

 
回到开始那句话,“在对它不了解的情况下,仅通过google就能解决问题,不正说明它不难掌握有大量资料可查吗,实在不行还能翻代码。” 这话有些道理,然而却存在一个问题,这个问题就是:

作为一个使用者,是否有能力解决遇到的问题,与是否有意愿去遇到并解决问题,是两回事。

你有本CPU设计手册,你可以说处理器很简单,但我只想看个电影啊?给你Linux内核的源码,你可以说内核设计不难掌握,但我只想跑个游戏啊?何况他们是否因此就变得不难了,也是值得怀疑的。

这其实反映了技术人的产品意识。

很多技术人员喜欢玩酷的东西,他们愿意去探索新的领域,把不可能的变为可能。但是很多时候,他们做出来的东西却很难使用。

有的库可以增加很多参数,参数之间却有耦合,导致你在采用的时候需要写很多设置代码,而有点库却只需要一行代码;有的服务功能众多,却需要用户学习繁杂的步骤,而有的服务却可以开箱即用;有的服务功能可以实现,却会有很多不稳定甚至崩溃的情况出现,等等。

对于实现的工程师来讲,可能最大的区别在于,你是否考虑从用户的角度审视过自己的东西。即使这个服务也许只是为其他技术人员使用的。

技术人员可以,也应该,让技术人员更幸福。

最后,聊聊架构为大家送上一个关于技术选型的小漫画。其实技术并没有错,错的也许是我们.....
R[Z}P6_7OS1Y}196XXK5Y.png

 
0
评论

一乐 :煎饼果子与架构模式 架构 环信

beyond 发表了文章 • 1974 次浏览 • 2016-04-18 12:13 • 来自相关话题

编者按:本文由一乐在高可用架构群分享,转载请注明来自高可用架构「 ArchNotes 」。



一乐是我,也是梁宇鹏。现任环信首席架构师兼 IM 技术总监,负责即时通讯云平台的整体研发和管理。曾任新浪微博通讯技术专家,负责微博通讯系统的设计与研发。一直专注在即时通讯领域,熟悉 XMPP 协议和相关的开源实现(包括 Jabberd2、EJabberd、Openfire)。关注分布式系统和高性能服务,关注 Erlang、Golang 和各种浪。

​煎饼的故事
有一段时间住在花园路,最难忘的就是路边的煎饼果子。老板每天晚上出来,正好是我加班回去的时间。

一勺面糊洒在锅上,刮子转一圈,再打一个蛋,依然刮平。然后啪的一下反过来,涂上辣酱,撒上葱花。空出手来,剥一根火腿肠。最后放上薄脆,咔咔咔三铲子断成三边直的长方形,折起来正好握在手中。烫烫的,一口咬下去,蛋香、酱辣、肠鲜,加上薄脆的声音和葱花的惊喜,所有的疲劳都一扫而光。




这种幸福感让我如此迷恋,以至于会在深宅的周末,穿戴整齐跑出去,就为了吃上一个。也因为理工科的恶习,我也情不自禁地开始思考这份执迷的原因,直到最后,我发现了它的秘密。
 
作为街头小吃的杰出代表,能够经历众口的挑剔而长盛不衰的秘密是什么?
 
 所有的一切全因为其模式。
而这模式与大多数互联网服务的架构如出一辙,那就是分层架构。

分层的设计意味着,每一层都独立承担单一的职责。

这在根本上降低了制作的难度。做饼的时候专心控制火候,做酱的时候专注在味道。每层职责的单一化也让优化变得简单,因为它是自然可伸缩的。你要是想多吃点蛋就多加一个,你要多吃点肠就多加一根,完全取决于你的胃口。
 
它又是可以扩展的。你可以不要蛋,你可以加根肠,你可以不要薄脆,你可以加上辣酱。而且每一层又是可定制的。葱花可以少一点,辣酱可以多一点,肠可以要两根,鸡蛋可以加三个。

你也可以把面饼换成面包,把鸡蛋换成煎蛋,把辣酱换成甜酱。你已经知道这是什么了吧?是的,你好,这里是赛百味,请问你要什么口味的三明治?

煎饼果子和三明治,其实本质上是相通的。而加一个蛋更香,也不是因为对蛋的追求,在根本上是因为煎饼果子模式的强大。

因为这种模式,一千个人可以有一千种煎饼果子。
而有了对模式的理解,对小吃的评估也就变得更加容易。比如肉夹馍只有馍和肉,二维切换单调不可长久;比如烤冷面,干脆就是满嘴的热烈混在一起,没有煎饼这样的表现层,整个面都散发着原始的不讲究。

这种对比上的简化,也让我们有了新的选择,保存宝贵的精力,并且可以随时放弃对细节的追究。




就像在我们谈论女人时,

(抱歉博主是男人)

我们在意胸、

在意腿、

在意风情、

在意温柔,

因为女人是有区别的。

当我们欣赏电影的时候,

我们在意男人、

在意女人、

在意老人、

在意孩子,

因为角色是有区别的。

当我们走在路上的时候,

我们在意行人、

在意车辆、

在意商店、

在意餐厅,

因为物体是有区别的。
我们在设计和优化系统的时候,其中的每个服务都是自行运转,做着自己份内的事,但是在不同的维度里,作用却变得不尽相同。

这也是我们讲优化要分层次和级别,架构、算法、库和 OS,而讲架构的时候,我们首先讲的是整体的模式,然后是具体的权衡,实现的细节则是最不重要的。

架构的模式
谈起这个,是因为 Mark Richards 写了一本架构模式的书《Software Architecture Pattens》。

书中总结对比了五种模式的优缺点,包括了 Layered、Event-Driven、Microkernel、Microservices、Space-Based。

书写得简单精致,推荐大家去阅读,地址见文末。

还有一种模式,因为在越来越多的系统中用到,是书中没有的(与 Space-Based 有所区别),但我觉得也有必要专门介绍下。我们开始在群发系统中实现,后来的抢购、红包和火车票的场景中也屡屡看到它的身影。


2013 年的时候,我们在微博做粉丝服务平台,一个类似微信公众号的群发系统。然而比后者更困难的是,当时在产品设计上并没有像微信一样新建用户体系,而是直接基于微博的粉丝关系,这就意味着一篇文章要能能在很短时间内支持亿级的用户推送。这个数量级的订阅用户,即使看今天的微信公众号依然是难以想象的。
当时有一套老的群发系统,都是基于 MySQL 的收件箱设计,在更换了 SSD 硬盘,又批量化数据库操作之后,整体写入性能依然只在每秒几万的级别,这就意味着一亿用户只能在 17 分钟内发完,我们意识到这套系统需要进行重新设计。

最终我们我们使用了一种新的架构方式,达到了每秒百万级别的速度,而且还可以更高。这种模式就是单元化架构。

下文介绍我参照了架构模式的说明方式,希望能够让大家有个对比,喜欢你可一定要说好!

单元化架构
如前所述,我们选择单元化的一个重要目的是为了性能,为了极高的性能。这比起一般的分层架构来讲,会获得更经济的结果,但也因此,牺牲了分层架构的一些特性,因为它的容量取决于单元的大小(关于单元等名词介绍,我会在下文介绍)。

虽然它支持按照单元扩容,但在单元内基本上每层的性能都是固定的。这更适合容量可预期的场景,比如大多数已经趋于稳定的业务。像前面的粉丝服务平台,虽然他下发消息量级巨大,但是在整体层面,使用平台的用户由于是 VIP 用户,其规模基本在在数百万级别,而粉丝量级也不太可能过亿。

重要的是,基于当时的业务数据,我们已经知道平均粉丝数在什么量级。而业务数据是架构选型的重要依据。商品秒杀、火车抢票等等都是一样。
 
当然也有例外。因为单元化架构作为一种思想,它不会局限在一台机器,一个机架,它也适用一个机房。当它的层次变大时,单元内自然就可以有变化的空间。每一层服务都可以分开伸缩。而到了这个层面,它的追求可能就完全不一样了。像阿里的双十一服务改造,会为了流量的分离,像 QQ 的聊天,会为了接入的速度。它们的基本思想是一致的。

至于单元化架构和煎饼果子的关系,我会在文后回答。




核心概念 Key Concepts
分区(Shard)是整体数据集的一个子集。如果你用尾号来划分用户,那么相同尾号的用户可以认为是同一分区。

单元(Cell)是满足某个分区所有业务操作的自包含的安装。我们从并行计算领域里借鉴了这个思想,也就是计算机体系结构里的 Celluar Architecture,在那里一个 Cell 是一个包含了线程部件、内存以及通讯组件的计算节点。 https://en.m.wikipedia.org/wik ... cture

单元化(Cellize)这是我的自造词,描述一个服务改造成单元架构的过程。

模式描述 Patten Description
单元架构最重要的概念,就是单元和单元的自治。

你可以将其想象成细胞,如之前所述,每个细胞都是自成一体,功能明确。你也可以将其想象成小隔间,就像你去了一个按摩院,每个隔间里都有技师和所有设备。我没有用前面那个名字,因为其有太强的生物学含义,也没有用后者,因为其有太多的服务性暗示。但是如果你有足够的想象力,其实什么名字都可以的。

说到单元的自治,即单元的自我协调和之间的隔离。单元既然做到了自包含,那么其中的所有组件,不管是否在物理上分离成了独立的服务,都是在一个单元内互相支持的,也就是跟其他单元内的同类和非同类组件都不会有任何交流。这也是跟基于空间的架构的重要区别,后者的处理单元之间还是会互相通信并同步信息。

这里的挑战就在于分区的算法。一个单元内的组件会很多,如果业务复杂,涉及到的数据也会很多,为了隔离,每一个组件都要能按照同样的算法进行分区。

本质上每个单元都是相似的,单元之间的区别或者取决于请求,或者取决于数据。而且越到大的层面,区分度越低,用户甚至是可以在不同单元间漫游的。

模式动力学 Patten Dynamics
单元架构的最典型目的,还是为了极高的性能,为了获得经济的高速度。这里一方面,是因为我们发现其他架构实际上是浪费了很多资源,每一层服务都运行在单独的操作系统上,而且都要通过局域网或者城域网中转。

与此同时,传统的互联网服务还是希望用一堆计算能力普通的节点来服务大量用户,而随着摩尔定律的推进,单机性能越来越高,网络通讯的成本随之变得耗费显著。这使得我们有机会也有动力在垂直方向进行扩展。

当你把更多的组件放在同一个地方的时候,你也在物理上获得了计算本地化的优势。这是我们获得性能提升的根本原因。

服务分成了很多单元,但总要跟外界通讯,这个事情是交给协调者 Coordinator 的。你可以在内部增加存储、缓存,增加队列和处理机,这些所有不交互的组件,理论上都不是外部资源可以访问的。

前面我们提到,单元化过程也是分区算法的应用过程。而这个分区算法放在哪里就是个问题。

我们可以封装运行库交给客户端,也可以做个代理层,内置算法。也有一些服务因为业务需要,请求需要复制到每个单元去。这就是典型的 Scatter-Gatter 模型,那么你还可能需要一个作业管理系统。这些都是可选择的使用方式。

模式分析 Patten Analysis
总体敏捷度低,易部署性低,可测试性高,性能高,伸缩性高,易开发性低。

基于篇幅原因,不再详述每一个方面,相信大家都能自行分析。唯一需要强调的是运维要求比较高。

单元化之后,所有的服务放在一起,在请求失败的情况下需要快速定位某个单元,这跟分层排除的思路是不一样的。如果运维团队不够高效,面对这样集群数量的暴涨(每个单元的服务数量相当于原来一个集群的服务数量),有可能是会被大量的工作压垮;如果运维团队分离比较明显,每种组件都是专门的团队来维护(这是我们在微博遇到的),那就会有排异反应的风险,因为每一个团队都有自己的权限和服务管理习惯,这里需要相当的协调工作来防止相互干扰。
后记

前面留的一个问题,煎饼果子跟单元化架构的关系。答案说起来很简单,你问问煎饼摊就知道了。

煎饼是分层的,煎饼摊是单元的。消息发送服务是单元的,但是索引维护是分层的。看模式要确定系统的范畴,从不同角度看,同样的东西是有不同意义的。这也是架构师要做的思考。

其实 IT 系统千百万,模式肯定不会止于这几种。但有了基础的模式,了解它们之间的相似和区别,对于我们设计自己的系统,思考其中的权衡都是有帮助的。
Q & A

1. 单元化设计与 Docker 的容器化思路是否相通?又有何差异呢?

一乐:应该是关注的点不一样,但不冲突。Docker 一般是在微服务架构下会使用的措施,但并不意味着不能用在其他架构上。一个单元内的各种组件,使用什么样的技术,都是新的选择。用 Docker 不错。

2. 对于分布式服务,单元化架构可能会带来数据一致性问题,这个一般如何解决?

一乐:可能我没有理解你场景,单元化一般不会带来一致性问题。因为 Sharding 之后,一块分区数据相当于完全属于一个单元,其他单元是被隔离访问的。


3. 单元化架构最小情况是单台机部署整体服务,资源方面如何规划?

一乐:这方面就要计算了,也就是进行容量规划,相信大家在这方面都很熟悉。一个需要注意的点是,单元化的架构应用在可预期的总体容量上时会省很多事。鉴于分区算法的固定,扩容方面,其实可以通过预先规划,在单机上再进行多单元混部的方式。

4. 单元与 app cluster(总服务器)之间是怎么进行关联的,是通过注册服务还是按照 hash 分派的,如果是 hash 分派,那么挂了怎么接回的,如果是注册服务,是怎么对应分派服务呢?

一乐:简单做就是 hash 分派,高级点就是注册服务,可以直接参照成熟的 Sharding 算法。任务只要到了单元内,就是单元自己的事了。如果你的 Job 有阶段性,可能要考虑 Job 状态记录以及请求处理的幂等性

5. 你觉得单元化架构的问题是什么?如果让你重新设计你会做哪些改进?

一乐:这个问题太聪明了,谢谢!单元化架构的问题,如之前所说,有一个扩容难题,有一个运维难题,有一个单点问题。扩容问题刚才说了,在三年前我们还没有 Docker 的时候,我们的服务隔离难度很大,现在已经今非昔比。一刀(Docker)在手,天下我有!单元的单点问题,你得考虑单元级别的主从同步,这方面常见的互联网技术就行。

6. 分布式架构经常讲究服务器无状态,这样可以单台服务器异常对整体服务无影响。但单元化意味着服务是有状态,如何保障高可用?

一乐:无状态只能是业务层,涉及到数据的不会无状态,因为数据就是状态的记录。保障高可用嘛,前面说了,先把主从做了吧。

7. 单元细胞内依然采用分层架构设计还是 ALL IN ONE 即可?

一乐:在讲单元化的时候,其实不要求单元内的组织模式,所以回答是都行。

8. “每秒百万级的推送” 除了采用这种单元化的架构模式使之成为可能对于基础的中间件如 队列 db 等的架构如何规划的?还要额外考虑哪些技术点或问题?

一乐:队列主要用来防峰,在高速服务里,如果再想扩容,肯定先走批量的路子。db 的规划其实是重点,单元化架构实际上算是以数据为中心的一种模式。额外的考虑其实跟之前都很像,不过要做一些特殊的处理,比如冷热数据的分离。
参考阅读

一个单元化架构的例子 http://t.cn/RqM5Ns0

Software Architecture Patterns http://www.oreilly.com/program ... s.csp

校长:技术成长四个阶段需要的架构知识
 
支撑微博千亿调用的轻量级RPC框架:Motan

Upsync:微博开源基于Nginx容器动态流量管理方案

小编:一乐最近也开了公众号,内容非常有特色,将复杂的道理说得如煎饼这么通透,所以别忘了识别二维码关注,错过这次小编琢磨最短都要再等一年。




本文策划庆丰,编辑王杰,想讨论更多架构设计,请关注公众号获取进群机会。转载请注明来自高可用架构「ArchNotes」微信公众号及包含以下二维码。 查看全部

640.webp_.jpg


编者按:本文由一乐在高可用架构群分享,转载请注明来自高可用架构「 ArchNotes 」。

640.webp_(1)_.jpg
一乐是我,也是梁宇鹏。现任环信首席架构师兼 IM 技术总监,负责即时通讯云平台的整体研发和管理。曾任新浪微博通讯技术专家,负责微博通讯系统的设计与研发。一直专注在即时通讯领域,熟悉 XMPP 协议和相关的开源实现(包括 Jabberd2、EJabberd、Openfire)。关注分布式系统和高性能服务,关注 Erlang、Golang 和各种浪。



​煎饼的故事

有一段时间住在花园路,最难忘的就是路边的煎饼果子。老板每天晚上出来,正好是我加班回去的时间。

一勺面糊洒在锅上,刮子转一圈,再打一个蛋,依然刮平。然后啪的一下反过来,涂上辣酱,撒上葱花。空出手来,剥一根火腿肠。最后放上薄脆,咔咔咔三铲子断成三边直的长方形,折起来正好握在手中。烫烫的,一口咬下去,蛋香、酱辣、肠鲜,加上薄脆的声音和葱花的惊喜,所有的疲劳都一扫而光。


640.webp_(2)_.jpg


这种幸福感让我如此迷恋,以至于会在深宅的周末,穿戴整齐跑出去,就为了吃上一个。也因为理工科的恶习,我也情不自禁地开始思考这份执迷的原因,直到最后,我发现了它的秘密。
 
作为街头小吃的杰出代表,能够经历众口的挑剔而长盛不衰的秘密是什么?


 
 所有的一切全因为其模式。

而这模式与大多数互联网服务的架构如出一辙,那就是分层架构。

分层的设计意味着,每一层都独立承担单一的职责。

这在根本上降低了制作的难度。做饼的时候专心控制火候,做酱的时候专注在味道。每层职责的单一化也让优化变得简单,因为它是自然可伸缩的。你要是想多吃点蛋就多加一个,你要多吃点肠就多加一根,完全取决于你的胃口。
 
它又是可以扩展的。你可以不要蛋,你可以加根肠,你可以不要薄脆,你可以加上辣酱。而且每一层又是可定制的。葱花可以少一点,辣酱可以多一点,肠可以要两根,鸡蛋可以加三个。

你也可以把面饼换成面包,把鸡蛋换成煎蛋,把辣酱换成甜酱。你已经知道这是什么了吧?是的,你好,这里是赛百味,请问你要什么口味的三明治?

煎饼果子和三明治,其实本质上是相通的。而加一个蛋更香,也不是因为对蛋的追求,在根本上是因为煎饼果子模式的强大。



因为这种模式,一千个人可以有一千种煎饼果子。

而有了对模式的理解,对小吃的评估也就变得更加容易。比如肉夹馍只有馍和肉,二维切换单调不可长久;比如烤冷面,干脆就是满嘴的热烈混在一起,没有煎饼这样的表现层,整个面都散发着原始的不讲究。

这种对比上的简化,也让我们有了新的选择,保存宝贵的精力,并且可以随时放弃对细节的追究。


640.webp_(1)_.jpg

就像在我们谈论女人时,

(抱歉博主是男人)

我们在意胸、

在意腿、

在意风情、

在意温柔,

因为女人是有区别的。

当我们欣赏电影的时候,

我们在意男人、

在意女人、

在意老人、

在意孩子,

因为角色是有区别的。

当我们走在路上的时候,

我们在意行人、

在意车辆、

在意商店、

在意餐厅,

因为物体是有区别的。


我们在设计和优化系统的时候,其中的每个服务都是自行运转,做着自己份内的事,但是在不同的维度里,作用却变得不尽相同。

这也是我们讲优化要分层次和级别,架构、算法、库和 OS,而讲架构的时候,我们首先讲的是整体的模式,然后是具体的权衡,实现的细节则是最不重要的。



架构的模式

谈起这个,是因为 Mark Richards 写了一本架构模式的书《Software Architecture Pattens》。

书中总结对比了五种模式的优缺点,包括了 Layered、Event-Driven、Microkernel、Microservices、Space-Based。

书写得简单精致,推荐大家去阅读,地址见文末。

还有一种模式,因为在越来越多的系统中用到,是书中没有的(与 Space-Based 有所区别),但我觉得也有必要专门介绍下。我们开始在群发系统中实现,后来的抢购、红包和火车票的场景中也屡屡看到它的身影。


2013 年的时候,我们在微博做粉丝服务平台,一个类似微信公众号的群发系统。然而比后者更困难的是,当时在产品设计上并没有像微信一样新建用户体系,而是直接基于微博的粉丝关系,这就意味着一篇文章要能能在很短时间内支持亿级的用户推送。这个数量级的订阅用户,即使看今天的微信公众号依然是难以想象的。
当时有一套老的群发系统,都是基于 MySQL 的收件箱设计,在更换了 SSD 硬盘,又批量化数据库操作之后,整体写入性能依然只在每秒几万的级别,这就意味着一亿用户只能在 17 分钟内发完,我们意识到这套系统需要进行重新设计。

最终我们我们使用了一种新的架构方式,达到了每秒百万级别的速度,而且还可以更高。这种模式就是单元化架构。

下文介绍我参照了架构模式的说明方式,希望能够让大家有个对比,喜欢你可一定要说好!



单元化架构

如前所述,我们选择单元化的一个重要目的是为了性能,为了极高的性能。这比起一般的分层架构来讲,会获得更经济的结果,但也因此,牺牲了分层架构的一些特性,因为它的容量取决于单元的大小(关于单元等名词介绍,我会在下文介绍)。

虽然它支持按照单元扩容,但在单元内基本上每层的性能都是固定的。这更适合容量可预期的场景,比如大多数已经趋于稳定的业务。像前面的粉丝服务平台,虽然他下发消息量级巨大,但是在整体层面,使用平台的用户由于是 VIP 用户,其规模基本在在数百万级别,而粉丝量级也不太可能过亿。

重要的是,基于当时的业务数据,我们已经知道平均粉丝数在什么量级。而业务数据是架构选型的重要依据。商品秒杀、火车抢票等等都是一样。
 
当然也有例外。因为单元化架构作为一种思想,它不会局限在一台机器,一个机架,它也适用一个机房。当它的层次变大时,单元内自然就可以有变化的空间。每一层服务都可以分开伸缩。而到了这个层面,它的追求可能就完全不一样了。像阿里的双十一服务改造,会为了流量的分离,像 QQ 的聊天,会为了接入的速度。它们的基本思想是一致的。

至于单元化架构和煎饼果子的关系,我会在文后回答。


640.webp_(3)_.jpg


核心概念 Key Concepts

分区(Shard)是整体数据集的一个子集。如果你用尾号来划分用户,那么相同尾号的用户可以认为是同一分区。

单元(Cell)是满足某个分区所有业务操作的自包含的安装。我们从并行计算领域里借鉴了这个思想,也就是计算机体系结构里的 Celluar Architecture,在那里一个 Cell 是一个包含了线程部件、内存以及通讯组件的计算节点。 https://en.m.wikipedia.org/wik ... cture

单元化(Cellize)这是我的自造词,描述一个服务改造成单元架构的过程。



模式描述 Patten Description

单元架构最重要的概念,就是单元和单元的自治

你可以将其想象成细胞,如之前所述,每个细胞都是自成一体,功能明确。你也可以将其想象成小隔间,就像你去了一个按摩院,每个隔间里都有技师和所有设备。我没有用前面那个名字,因为其有太强的生物学含义,也没有用后者,因为其有太多的服务性暗示。但是如果你有足够的想象力,其实什么名字都可以的。

说到单元的自治,即单元的自我协调和之间的隔离。单元既然做到了自包含,那么其中的所有组件,不管是否在物理上分离成了独立的服务,都是在一个单元内互相支持的,也就是跟其他单元内的同类和非同类组件都不会有任何交流。这也是跟基于空间的架构的重要区别,后者的处理单元之间还是会互相通信并同步信息。

这里的挑战就在于分区的算法。一个单元内的组件会很多,如果业务复杂,涉及到的数据也会很多,为了隔离,每一个组件都要能按照同样的算法进行分区。

本质上每个单元都是相似的,单元之间的区别或者取决于请求,或者取决于数据。而且越到大的层面,区分度越低,用户甚至是可以在不同单元间漫游的。



模式动力学 Patten Dynamics

单元架构的最典型目的,还是为了极高的性能,为了获得经济的高速度。这里一方面,是因为我们发现其他架构实际上是浪费了很多资源,每一层服务都运行在单独的操作系统上,而且都要通过局域网或者城域网中转。

与此同时,传统的互联网服务还是希望用一堆计算能力普通的节点来服务大量用户,而随着摩尔定律的推进,单机性能越来越高,网络通讯的成本随之变得耗费显著。这使得我们有机会也有动力在垂直方向进行扩展。

当你把更多的组件放在同一个地方的时候,你也在物理上获得了计算本地化的优势。这是我们获得性能提升的根本原因。

服务分成了很多单元,但总要跟外界通讯,这个事情是交给协调者 Coordinator 的。你可以在内部增加存储、缓存,增加队列和处理机,这些所有不交互的组件,理论上都不是外部资源可以访问的。

前面我们提到,单元化过程也是分区算法的应用过程。而这个分区算法放在哪里就是个问题。

我们可以封装运行库交给客户端,也可以做个代理层,内置算法。也有一些服务因为业务需要,请求需要复制到每个单元去。这就是典型的 Scatter-Gatter 模型,那么你还可能需要一个作业管理系统。这些都是可选择的使用方式。



模式分析 Patten Analysis

总体敏捷度低,易部署性低,可测试性高,性能高,伸缩性高,易开发性低。

基于篇幅原因,不再详述每一个方面,相信大家都能自行分析。唯一需要强调的是运维要求比较高。

单元化之后,所有的服务放在一起,在请求失败的情况下需要快速定位某个单元,这跟分层排除的思路是不一样的。如果运维团队不够高效,面对这样集群数量的暴涨(每个单元的服务数量相当于原来一个集群的服务数量),有可能是会被大量的工作压垮;如果运维团队分离比较明显,每种组件都是专门的团队来维护(这是我们在微博遇到的),那就会有排异反应的风险,因为每一个团队都有自己的权限和服务管理习惯,这里需要相当的协调工作来防止相互干扰。


后记

前面留的一个问题,煎饼果子跟单元化架构的关系。答案说起来很简单,你问问煎饼摊就知道了。

煎饼是分层的,煎饼摊是单元的。消息发送服务是单元的,但是索引维护是分层的。看模式要确定系统的范畴,从不同角度看,同样的东西是有不同意义的。这也是架构师要做的思考。

其实 IT 系统千百万,模式肯定不会止于这几种。但有了基础的模式,了解它们之间的相似和区别,对于我们设计自己的系统,思考其中的权衡都是有帮助的。


Q & A

1. 单元化设计与 Docker 的容器化思路是否相通?又有何差异呢?

一乐:应该是关注的点不一样,但不冲突。Docker 一般是在微服务架构下会使用的措施,但并不意味着不能用在其他架构上。一个单元内的各种组件,使用什么样的技术,都是新的选择。用 Docker 不错。

2. 对于分布式服务,单元化架构可能会带来数据一致性问题,这个一般如何解决?

一乐:可能我没有理解你场景,单元化一般不会带来一致性问题。因为 Sharding 之后,一块分区数据相当于完全属于一个单元,其他单元是被隔离访问的。


3. 单元化架构最小情况是单台机部署整体服务,资源方面如何规划?

一乐:这方面就要计算了,也就是进行容量规划,相信大家在这方面都很熟悉。一个需要注意的点是,单元化的架构应用在可预期的总体容量上时会省很多事。鉴于分区算法的固定,扩容方面,其实可以通过预先规划,在单机上再进行多单元混部的方式。

4. 单元与 app cluster(总服务器)之间是怎么进行关联的,是通过注册服务还是按照 hash 分派的,如果是 hash 分派,那么挂了怎么接回的,如果是注册服务,是怎么对应分派服务呢?

一乐:简单做就是 hash 分派,高级点就是注册服务,可以直接参照成熟的 Sharding 算法。任务只要到了单元内,就是单元自己的事了。如果你的 Job 有阶段性,可能要考虑 Job 状态记录以及请求处理的幂等性

5. 你觉得单元化架构的问题是什么?如果让你重新设计你会做哪些改进?

一乐:这个问题太聪明了,谢谢!单元化架构的问题,如之前所说,有一个扩容难题,有一个运维难题,有一个单点问题。扩容问题刚才说了,在三年前我们还没有 Docker 的时候,我们的服务隔离难度很大,现在已经今非昔比。一刀(Docker)在手,天下我有!单元的单点问题,你得考虑单元级别的主从同步,这方面常见的互联网技术就行。

6. 分布式架构经常讲究服务器无状态,这样可以单台服务器异常对整体服务无影响。但单元化意味着服务是有状态,如何保障高可用?

一乐:无状态只能是业务层,涉及到数据的不会无状态,因为数据就是状态的记录。保障高可用嘛,前面说了,先把主从做了吧。

7. 单元细胞内依然采用分层架构设计还是 ALL IN ONE 即可?

一乐:在讲单元化的时候,其实不要求单元内的组织模式,所以回答是都行。

8. “每秒百万级的推送” 除了采用这种单元化的架构模式使之成为可能对于基础的中间件如 队列 db 等的架构如何规划的?还要额外考虑哪些技术点或问题?

一乐:队列主要用来防峰,在高速服务里,如果再想扩容,肯定先走批量的路子。db 的规划其实是重点,单元化架构实际上算是以数据为中心的一种模式。额外的考虑其实跟之前都很像,不过要做一些特殊的处理,比如冷热数据的分离。


参考阅读

一个单元化架构的例子 http://t.cn/RqM5Ns0

Software Architecture Patterns http://www.oreilly.com/program ... s.csp

校长:技术成长四个阶段需要的架构知识
 
支撑微博千亿调用的轻量级RPC框架:Motan

Upsync:微博开源基于Nginx容器动态流量管理方案



小编:一乐最近也开了公众号,内容非常有特色,将复杂的道理说得如煎饼这么通透,所以别忘了识别二维码关注,错过这次小编琢磨最短都要再等一年。

640.webp_(4)_.jpg


本文策划庆丰,编辑王杰,想讨论更多架构设计,请关注公众号获取进群机会。转载请注明来自高可用架构「ArchNotes」微信公众号及包含以下二维码。

640.webp_(5)_.jpg


0
评论

环信首席架构师:一个单元化架构的例子 架构

beyond 发表了文章 • 1330 次浏览 • 2016-04-11 14:14 • 来自相关话题

微博粉丝服务平台在单元化架构方面的实践已经在QCon讲过,这次重又写起文章,我想传播知识已经不那么重要(单元化架构不是创新,稍后会详细介绍),更重要的是还是希望能够借此引起诸位的思考,能够在架构层面多投入精力思考和尝试。
 
为什么要有架构实践?

很多人喜欢的是细节,因为有句名言叫魔鬼在细节里,于是都去细节里寻找魔鬼。但是打败了魔鬼就能看到天使么?未必。细节其实是最容易掌握的部分,细节之外还有很多。就像有了水泥和沙子,你能够做出混凝土,但是离建成高楼大厦还有很长的路要走一样,你要学着去设计架构。

但是事情并没有完,就像没有唯一的真理一样,架构也并不是只有一种。你不可能一朝学会,从此天下无敌。如果要赈灾,你需要的是帐篷,如果要重建,你需要的是瓦房。不同的住所需要的是不同的架构。
 
不同的服务也需要不同的架构设计,这也就是我们需要架构实践的重要原因。在这之后的原因,是我们做任何服务,都要考虑服务的性能和成本。

但优化有很多方式,为什么是架构呢?诚然,从硬件到操作系统,从共享库到应用软件,从算法到架构,每一层都可以优化,但每一层所做的工作量和收益也都是不同的。架构可能是需要投入最多精力的,但在很多时候却也是很少的可以提供超过数量级的提升方式。

所以,思维方式的转变才是你最应该在意的部分,单元化只是一个例子,而粉丝服务平台只是这个例子的例子,而已。

言归正传,接下来本文将从三个问题来介绍这次实践,单元化是什么,为什么要用以及我们如何做到的。

 
1. 单元化是什么

单元化架构是从并行计算领域发展而来。在分布式服务设计领域,一个单元(Cell)就是满足某个分区所有业务操作的自包含的安装。而一个分区(Shard),则是整体数据集的一个子集,如果你用尾号来划分用户,那同样尾号的那部分用户就可以认为是一个分区。单元化就是将一个服务设计改造让其符合单元特征的过程。




图 1 :洋葱细胞的显微镜截图,单元化要达到的目的就是让每个单元像细胞一样独立工作
在传统的服务化架构下(如下图),服务是分层的,每一层使用不同的分区算法,每一层都有不同数量的节点,上层节点随机选择下层节点。当然这个随机是比较而言的。




图 2 :传统的服务化架构,为伸缩性设计,上层节点随机选择下层节点
与其不同的是,在单元化架构下,服务虽然分层划分,但每个单元自成一体。按照层次来讲的话,所有层使用相同的分区算法,每一层都有相同数量的节点,上层节点也会访问指定的下层节点。因为他们已经在一起。




图 3 :单元化架构,为性能和隔离性而设计,上层节点访问指定下层节点
 
 2. 为什么要用单元化

在性能追求和成本限制的情况下,我们需要找到一种合适的方法来满足服务需求。在传统的分布式服务设计,我们考虑的更多是每个服务的可伸缩性,当各个服务独立设计时你就要在每一层进行伸缩性的考虑。这是服务化设计(SOA)流行的原因,我们需要每个服务能够单独水平扩展。
但是在摩尔定律下,随着硬件的不断升级,计算机硬件能力已经越来越强,CPU越来越快,内存越来越大,网络越来越宽。这让我们看到了在单台机器上垂直扩展的机会。尤其是当你遇到一个性能要求和容量增长可以预期的业务,单元化给我们提供另外的机会,让我们可以有效降低资源的使用,提供更高性能的服务。

总体而言,更高性能更低成本是我们的主要目标,而经过单元化改造,我们得以用更少(约二分之一)的机器,获得了比原来更高(接近百倍)的性能。性能的提升很大部分原因在于服务的本地化,而服务的集成部署又进一步降低了资源的使用。

当然除了性能收益,如果你做到了,你会发现还有很多收益,比如更好的隔离性,包括请求隔离和资源隔离,比如更友好的升级,产品可以灰度发布等。单元化改造后对高峰的应对以及扩容方式等问题,各位可以参考#微博春节技术保障系列#中的单元化架构文章,也不在此一一赘述。


3. 我们如何做到

此次单元化改造基于微博现有的业务,因此这里也先行介绍一下。粉丝服务平台是微博的内容推送系统(代号Castalia),可为V用户提供向其粉丝推送高质量内容的高速通道(单元化之后已到达百万条每秒)。整个服务涉及用户筛选、发送计费、屏蔽检查、限流控制和消息群发等多个子服务。由于改造思想相通,这里以用户筛选和消息群发两个服务为例,下面两图分别为商业群发在服务化思想和单元化思想下不同的架构。




图 4: 服务化思想下的商业群发架构设计(旧版)




图 5 :商业群发在单元化思想下的架构设计(新版)
对于筛选服务,在服务化架构里,需要去粉丝服务获取粉丝关系,然后去特征服务进行用户特征筛选,最后将筛选结果传输到群发服务器上;而在单元化架构里,粉丝关系直接就在本地文件中,用户特征服务也在本地,最后的筛选结果再不需要传输。服务本地化(粉丝关系和用户特征存储)减去了网络开销,降低了服务延时,还同时提高了访问速度和稳定性,而筛选结果本地存储又进一步节省了带宽并降低了延迟。以百万粉丝为例,每次网络操作的减少节省带宽8M左右,延时也从400ms降为0。

群发服务同样如此。由于在服务化架构里,我们使用MySQL和Memcache的方案,由于关系数据库的写入性能问题,中间还有队列以及相应的队列处理机,所有四个模块都有单独的机器提供服务,而在单元化架构里,四合一之后,只需要一套机器。当然机器的配置可能会有所提升,但真正计算之后你就会发现其实影响微乎其微。原因除了前面介绍的硬件增长空间外,上架机器的基本配置变高也是一个原因。而且,在单元化方案里,当我们把缓存部署在本地之后,其性能还有了额外的20%提升。


一些业务特有问题

不过群发这个场景,我们也遇到了一些特定的问题,一是分区问题,一是作业管理。这里也与各位分享下我们的解决方法。

分区问题分区问题其实是每个服务都会遇到的,但单元化后的挑战在于让所有服务都适配同一分区算法,在我们的场景下,我们按照接收者进行了分区,即从底层往上,每一层都来适配此分区算法。这里有特例的是用户特征和屏蔽服务,由于总体容量都很小,我们就没有对数据进行分区,所有单元内都是同一套全量数据,都是一个外部全量库的从库。不过由于本单元内的上层服务的关系,只有属于本分区的用户数据被访问到。所以,适配同一分区算法在某种程度上讲,可以兼容即可。

作业管理按照前面的分区方式,将群发服务的整体架构变成了一个类似Scatter-Gather+CQRS的方案,因为Gather不是一个请求处理的必须要素。也就是说,一个群发请求会被扩散到所有单元中,每个单元都要针对自己分区内的用户处理这个群发请求。广播方式的引入,使得我们首先需要在前端机进行分单元作业的处理监控,我们在此增加了持久化队列来解决。同时,由于单元内每个服务也都是单独维护的,作业可能在任何时间中断,因此每个作业在单元内的状态也都是有记录的,以此来达到作业的可重入和幂等性,也就可以保证每个作业都可以在任何时间重做,但不会重复执行。

除此之外,我们还对服务器进行了更为精细的控制,使用CPU绑定提高多服务集成部署时的整体效率,使用多硬盘设计保证每个服务的IO性能,通过主从单元的读写分离来提高整体服务等等。

后记

我平时不善文章,现在要成文发表,还是有一点紧张的。不过想到或许可以抛砖引玉,有机会向各位大牛学习,或者跟各位同学一起交流,内心又有些许期待。关于微博或者其他任何网站的设计,欢迎大家一起探讨,随时在微博恭候。





  查看全部
微博粉丝服务平台在单元化架构方面的实践已经在QCon讲过,这次重又写起文章,我想传播知识已经不那么重要(单元化架构不是创新,稍后会详细介绍),更重要的是还是希望能够借此引起诸位的思考,能够在架构层面多投入精力思考和尝试。
 
为什么要有架构实践?

很多人喜欢的是细节,因为有句名言叫魔鬼在细节里,于是都去细节里寻找魔鬼。但是打败了魔鬼就能看到天使么?未必。细节其实是最容易掌握的部分,细节之外还有很多。就像有了水泥和沙子,你能够做出混凝土,但是离建成高楼大厦还有很长的路要走一样,你要学着去设计架构。

但是事情并没有完,就像没有唯一的真理一样,架构也并不是只有一种。你不可能一朝学会,从此天下无敌。如果要赈灾,你需要的是帐篷,如果要重建,你需要的是瓦房。不同的住所需要的是不同的架构。
 
不同的服务也需要不同的架构设计,这也就是我们需要架构实践的重要原因。在这之后的原因,是我们做任何服务,都要考虑服务的性能和成本。

但优化有很多方式,为什么是架构呢?诚然,从硬件到操作系统,从共享库到应用软件,从算法到架构,每一层都可以优化,但每一层所做的工作量和收益也都是不同的。架构可能是需要投入最多精力的,但在很多时候却也是很少的可以提供超过数量级的提升方式。

所以,思维方式的转变才是你最应该在意的部分,单元化只是一个例子,而粉丝服务平台只是这个例子的例子,而已。

言归正传,接下来本文将从三个问题来介绍这次实践,单元化是什么,为什么要用以及我们如何做到的。

 
1. 单元化是什么

单元化架构是从并行计算领域发展而来。在分布式服务设计领域,一个单元(Cell)就是满足某个分区所有业务操作的自包含的安装。而一个分区(Shard),则是整体数据集的一个子集,如果你用尾号来划分用户,那同样尾号的那部分用户就可以认为是一个分区。单元化就是将一个服务设计改造让其符合单元特征的过程。

640.webp_.jpg

图 1 :洋葱细胞的显微镜截图,单元化要达到的目的就是让每个单元像细胞一样独立工作


在传统的服务化架构下(如下图),服务是分层的,每一层使用不同的分区算法,每一层都有不同数量的节点,上层节点随机选择下层节点。当然这个随机是比较而言的。

640.webp_(1)_.jpg

图 2 :传统的服务化架构,为伸缩性设计,上层节点随机选择下层节点


与其不同的是,在单元化架构下,服务虽然分层划分,但每个单元自成一体。按照层次来讲的话,所有层使用相同的分区算法,每一层都有相同数量的节点,上层节点也会访问指定的下层节点。因为他们已经在一起。

640.jpg

图 3 :单元化架构,为性能和隔离性而设计,上层节点访问指定下层节点


 
 2. 为什么要用单元化

在性能追求和成本限制的情况下,我们需要找到一种合适的方法来满足服务需求。在传统的分布式服务设计,我们考虑的更多是每个服务的可伸缩性,当各个服务独立设计时你就要在每一层进行伸缩性的考虑。这是服务化设计(SOA)流行的原因,我们需要每个服务能够单独水平扩展。
但是在摩尔定律下,随着硬件的不断升级,计算机硬件能力已经越来越强,CPU越来越快,内存越来越大,网络越来越宽。这让我们看到了在单台机器上垂直扩展的机会。尤其是当你遇到一个性能要求和容量增长可以预期的业务,单元化给我们提供另外的机会,让我们可以有效降低资源的使用,提供更高性能的服务。

总体而言,更高性能更低成本是我们的主要目标,而经过单元化改造,我们得以用更少(约二分之一)的机器,获得了比原来更高(接近百倍)的性能。性能的提升很大部分原因在于服务的本地化,而服务的集成部署又进一步降低了资源的使用。

当然除了性能收益,如果你做到了,你会发现还有很多收益,比如更好的隔离性,包括请求隔离和资源隔离,比如更友好的升级,产品可以灰度发布等。单元化改造后对高峰的应对以及扩容方式等问题,各位可以参考#微博春节技术保障系列#中的单元化架构文章,也不在此一一赘述。


3. 我们如何做到

此次单元化改造基于微博现有的业务,因此这里也先行介绍一下。粉丝服务平台是微博的内容推送系统(代号Castalia),可为V用户提供向其粉丝推送高质量内容的高速通道(单元化之后已到达百万条每秒)。整个服务涉及用户筛选、发送计费、屏蔽检查、限流控制和消息群发等多个子服务。由于改造思想相通,这里以用户筛选和消息群发两个服务为例,下面两图分别为商业群发在服务化思想和单元化思想下不同的架构。

640.webp_(2)_.jpg

图 4: 服务化思想下的商业群发架构设计(旧版)
640.webp_(3)_.jpg

图 5 :商业群发在单元化思想下的架构设计(新版)


对于筛选服务,在服务化架构里,需要去粉丝服务获取粉丝关系,然后去特征服务进行用户特征筛选,最后将筛选结果传输到群发服务器上;而在单元化架构里,粉丝关系直接就在本地文件中,用户特征服务也在本地,最后的筛选结果再不需要传输。服务本地化(粉丝关系和用户特征存储)减去了网络开销,降低了服务延时,还同时提高了访问速度和稳定性,而筛选结果本地存储又进一步节省了带宽并降低了延迟。以百万粉丝为例,每次网络操作的减少节省带宽8M左右,延时也从400ms降为0。

群发服务同样如此。由于在服务化架构里,我们使用MySQL和Memcache的方案,由于关系数据库的写入性能问题,中间还有队列以及相应的队列处理机,所有四个模块都有单独的机器提供服务,而在单元化架构里,四合一之后,只需要一套机器。当然机器的配置可能会有所提升,但真正计算之后你就会发现其实影响微乎其微。原因除了前面介绍的硬件增长空间外,上架机器的基本配置变高也是一个原因。而且,在单元化方案里,当我们把缓存部署在本地之后,其性能还有了额外的20%提升。


一些业务特有问题

不过群发这个场景,我们也遇到了一些特定的问题,一是分区问题,一是作业管理。这里也与各位分享下我们的解决方法。

分区问题分区问题其实是每个服务都会遇到的,但单元化后的挑战在于让所有服务都适配同一分区算法,在我们的场景下,我们按照接收者进行了分区,即从底层往上,每一层都来适配此分区算法。这里有特例的是用户特征和屏蔽服务,由于总体容量都很小,我们就没有对数据进行分区,所有单元内都是同一套全量数据,都是一个外部全量库的从库。不过由于本单元内的上层服务的关系,只有属于本分区的用户数据被访问到。所以,适配同一分区算法在某种程度上讲,可以兼容即可。

作业管理按照前面的分区方式,将群发服务的整体架构变成了一个类似Scatter-Gather+CQRS的方案,因为Gather不是一个请求处理的必须要素。也就是说,一个群发请求会被扩散到所有单元中,每个单元都要针对自己分区内的用户处理这个群发请求。广播方式的引入,使得我们首先需要在前端机进行分单元作业的处理监控,我们在此增加了持久化队列来解决。同时,由于单元内每个服务也都是单独维护的,作业可能在任何时间中断,因此每个作业在单元内的状态也都是有记录的,以此来达到作业的可重入和幂等性,也就可以保证每个作业都可以在任何时间重做,但不会重复执行。

除此之外,我们还对服务器进行了更为精细的控制,使用CPU绑定提高多服务集成部署时的整体效率,使用多硬盘设计保证每个服务的IO性能,通过主从单元的读写分离来提高整体服务等等。

后记

我平时不善文章,现在要成文发表,还是有一点紧张的。不过想到或许可以抛砖引玉,有机会向各位大牛学习,或者跟各位同学一起交流,内心又有些许期待。关于微博或者其他任何网站的设计,欢迎大家一起探讨,随时在微博恭候。

640.webp_(4)_.jpg