阿里云
阿里云多端小程序中小企业获客首选
发表主题 回复主题
  • 21245阅读
  • 11回复

[免费公测]【阿里云产品公测】OTS使用之简单线上产品实践基于PythonSDK

级别: 菜鸟
发帖
52
云币
192
OTS使用之简单线上产品实践--基于PythonSDK L0{ehpvM  
e2~i@vq  
g->cgExj  
实践是检验真理的唯一标准,学习技术需要通过实践过程中的不断尝试,才能够快速掌握要领。OTS是构建在阿里飞天分布式系统之上的NoSQL数据库服务,提供海量结构化数据的存储和实时访问。刚好想用手上的一台ECS做点什么,既然如此,那就通过搭建简单线上产品(alijot.com 快速记)的过程,学习下NoSQL数据库OTS吧 >pKu G#  
----------------------------------------------------------------------------------------------------------------------------------------------------------- N@UO8'"9K&  
  • 服务器配置CPU:1核  内存:1GB  数据盘:15G  带宽:1Mbps
]k[y#oB  
  • 产品定位:基于阿里云存储的快速记服务,PC,手机端通用
  • 产品功能:目前提供基础记事功能,动定时(间隔5s)存储,避免编辑过程中的意外(后期将采用oss支持云盘,完善记录逻辑及体验)
yQ> *F  
----------------------------------------------------------------------------------------------------------------------------------------------------------- gIR{!'  
OTS数据库设计(初步): |q?I(b4Q@  
PgZ~of&  
fL7ym,?  
  • OTS基本概念:
YX+Da"\  
1.主键,属性,分片键: `vJ+ sRf  
OTS 数据模型概念包括表、行、主键和属性。主键和属性是读写操作的关键,通过传入主键作为索引值,传入属性值作为要查询的数据(属性键是可变的)。主键最多支持4个主键列,组成主键的第一个主键列又称为分片键,  好的OTS数据表设计中,分片键可以保证是唯一且无连续(并发无序),能够很好的满足分片的特性。OTS 按照分片键的范围对表的数据进行分区,拥有相同分片键的行会被划分到同一个分片。为了防止分片过大无法切分,OTS 对单个分片键下的数据量做出了限制。单个分片键下的所有行数据大小之和不能超过 1GB。 |[x) %5F  
8H_3.MK  
2.吞吐量: B$b'bw.  
关于吞吐量的概念,文档有介绍,以1KB 向上取整计算,如果指定的范围内没有数据,则消耗 1 读服务能力单元,目前最大读写吞吐量都为5000。举个学生一卡通的例子:当数据以时间作为分片键时,已经毕业的学生的卡片,不会再产生消费记录。假如 CardID 是随着卡片申请时间递增的,以 CardID 作为分片键,会导致已经毕业的学生的 CardID 没有访问压力却被分配到预留读写吞吐量,造成浪费。处理方法是将已经超出维护年限的消费记录表中的数据导出,存入 OSS(Open Storage Service) 归档,或直接删除。 2U6j?MyH2  
6KmF 9  
T!o 4k  
3.合理存储: rvRtR/*?j  
将原始数据顺序打乱后再进行导入。保证写入数据均匀的分配在各个分片键上。或者使用多个工作线程并行导入数据。把大的数据集合切分成很多个小集合。工作线程随机选取小集合进行数据导入。 apk06"/  
EJYfk?(B  
&$fe%1#  
  • 基于以上基本规则进行数据表设计:
Ue|]M36  
`Nnqdc2  
首先,列出和数据库有关的需求: *B(na+  
1.用户注册,登录,登出,用户信息的获取 H"8+[.xBh  
2.快速记 记录的存储及查看记录时数据读取以后的组织逻辑 7>EjP&l  
3.需要保证用户查询和写入的速度 eRllF` *  
;p%a!Im_ <  
V|vU17Cgy  
然后,进行需求分析: Fs7/3  
1.用户相关数据有 用户名,密码,状态,权限,等级,注册时间,个人信息,记录创建时间列表。 (因为需要保证分片均匀,我采用用户名做主键,且为分片键) Zs!)w9y&V  
2.记录的相关数据有 记录创建时间,所属用户,状态,类型,内容,自动保存的改变内容及时间。 @Nb&f<+gi  
3.取数据时,我首先要确认用户信息,然后通过当前用户的用户名,找到用户的所有记录值,日期作为主键mid值,保证唯一性,然后写入到OTS中。官方文档似乎没有找到通过属性键找数据的方法,所以我选择把记录的主键放到用户的属性键来获取数据。我还需要根据属性值排序且根据范围读取的功能,以满足用户查看某几天记录的需求,于是我看到了一个方法get_range OTS产品文档” 第28页的GetRange方法,SKD中的DOCTMENT也有出现): vyT$IdV2  
get_range(self, table_name, direction, inclusive_start_primary_key, exclusive_end_primar    y_key, columns_to_get=None, limit=None) s%`o  
说明:根据范围条件获取多行数据。 H@er"boi  
``table_name``是对应的表名 =rS z>l  
``direction``表示范围的方向,字符串格式,取值包括'FORWARD'和'BACKWARD' 4f~hd-z  
``inclusive_start_primary_key``表示范围的起始主键(在范围内) li\hHd5  
``exclusive_end_primary_key``表示范围的结束主键(不在范围内) $53I%.  
``columns_to_get``是可选参数,表示要获取的列的名称列表,类型为list;如果不填,表示获取所有列。 Nzz" w_#  
``limit``是可选参数,表示最多读取多少行;如果不填,则没有 xmZ]mu,,$  
示例 ,WbO8#z+  
    inclusive_start_primary_key = {'gid':1, 'uid':INF_MIN} 7,ODh-?ez  
    exclusive_end_primary_key = {'gid':4, 'uid':INF_MAX} RLr;]j8cm  
    columns_to_get = ['name', 'address', 'mobile', 'age'] |SXMd'<3`Z  
    consumed, next_start_primary_key, row_list = ots_client.get_range( =x}27f%-Mg  
                'myTable', 'FORWARD', %"@KuqV  
                inclusive_start_primary_key, exclusive_end_primary_key, +r9:n(VP  
                columns_to_get, 100 nm 66U4.@  
    ) ^r73(8{)  
返回值 J=W"FEXTL7  
``consumed``表示本次操作消耗的CapacityUnit,是ots2.metadata.CapacityUnit类的实例 ?f[#O&#  
``next_start_primary_key``表示下次get_range操作的起始点的主健列,类型为dict 0*W=u-|s6  
``row_list``表示本次操作返回的行数据列表,格式为:[(primary_key_columns,attribute_columns), ...] R@t?!`f!+  
9>d$a2 nc  
(在这里踩了个坑,毕竟是第一次接触NoSQL,嘿嘿。。。不同表分片键可以相同,而且分片键才是取数据的关键,当然,如果主键中有多个属性,那么查询的时候就必须把所有的主属性都传入,否则会报错哦。我就是以时间作为分片键,原以为两个值同时构成取数据的制约,结果导致根据时间取出的数据是所有用户的数据,囧,所有重新设计了数据库) :<Y,^V(  
R1/ )Yy  
最后,初步设定表结构(似乎很简单,原谅我是新手): MzsDWx;eJ  
1 user | joter | pwd,status,power,range,date,info,modatestart,modatelast ]~CG zV  
用户表:用户名,密码,状态,权限,等级,注册时间,个人信息,记录创建时间列表 ~j",ePl  
2 modify | joter,modate | status,type,title,content ^,'!j/w5  
记录表:用户名(分片),记录创建时间,状态,类型,标题,内容 bl(rCbj(w  
Z.<OtsQN  
&%L1n?>Q}  
v7T05  
y^=\w?d  
可以看到,创建表时只用跟上吞吐量和主键,体现了属性值的可变性。 5`*S'W}\>  
0Pu$1Fp  
] 7_ f'M1F  
  • 有关OTS数据库操作的具体实现:
^k]OQc7q'  
首先需要下载SDK并且安装,我使用了Python SDK,下载地址在OTS介绍页面(文章末尾给出地址),需要python2.7,个人使用的服务器系统是ubuntu,如果选择centos需要自行升级python版本。 Y~hBVz2g  
:84fd\It4  
在调用代码之前需要加入以下导包代码: U-#wFc2N  
3i=+ [  
from ots2 import *ENDPOINT = 'http://isdot.cn-hangzhou.ots.aliyuncs.com/' a,U[$c  
ACCESSID = 'TjfCaKv5YTjf8aBavUaKvD'ACCESSKEY = 'w5nB9tfrSuBd5xzd5UFrdtQocxhAH3IOV' ihBlP\C  
INSTANCENAME = 'isdot'ots_client = OTSClient(ENDPOINT, ACCESSID, ACCESSKEY, INSTANCENAME) :w:hqe|_  
#以上代码中KEY无效,不必尝试;ACCESSID和ACCESSKEY大概就是这样长短的两个值,需要你在面板里获取 -("sp  
ZGf R:a)wc  
0.创建,删除表的工作可以很方便的在web端操作 03L+[F&"?  
NGtSC_~d  
9lNO ~8  
1.注册 i[sHPEml(5  
通过主键joter随意获取任意值 如pwd,判断是否存在用户: iyAeR!`  
f/&gR5  
primary_key = {'joter':name}        # 主键 !#` .Mv Z  
columns_to_get = ['pwd']         # 属性 BSYJ2   
consumed, primary_key_columns, attribute_columns = ots_client.get_row('alijot_user', primary_key, columns_to_get) !E8y!|7$  
#变量 consumed代表返回的状态信息,如:存储消耗的写CapacityUnit值的变量应该是这样的 consumed.write =<MSM\Rb  
#primary_key_columns 代表取得的主键值,在批量获取数据的时候用的到 n=WwB(}q  
#attribute_columns 代表取得的熟悉值,通过attribute_columns.get('power')获取具体值 |RS9N_eRt  
#方法 get_row为通过主键获取单行 b1JXC=*@  
Md mS  
S\b[Bq  
将用户信息插入数据库的操作: -b"mx"'?  
primary_key = {'joter':name} #kjN!S*=  
attribute_columns = {'pwd':pwd, 'power':12} {fFZ%$  
condition = Condition('EXPECT_NOT_EXIST')     #判断的调节,当不存在 uOUgU$%zqH  
consumed = ots_client.put_row('alijot_user', condition, primary_key, attribute_columns)       uP2e/a  
#put_row方法是单行插入 k#X~+}N^  
:_V9Jwu  
2.登录 /5 yjON{  
 BC*62m  
primary_key = {'joter':name} x`~YTOfYk  
columns_to_get = ['pwd', 'power'] 'ol8lIa.P  
consumed, primary_key_columns, attribute_columns = ots_client.get_row('alijot_user', primary_key, columns_to_get) RQxL`7H  
#判断attribute_columns 是否为空来得到用户名是否正确以及通过判断pwd==attribute_columns.get('pwd')确定密码是否正确 ~A^E_  
#0>??]&r  
3.读取用户信息 uqy&P S  
n'*4zxAA  
name = self.get_secure_cookie("test")      #获取cookie值 M|8vP53=q  
primary_key = {'joter':name}   U[7 &   
columns_to_get = ['pwd', 'power']     BV)o F2b:  
consumed, primary_key_columns, attribute_columns = ots_client.get_row('alijot_user', primary_key, columns_to_get) c IK  
l@:Tw.+/9  
print u'成功读取数据,消耗的读CapacityUnit为:%s' % consumed.read      #输出读写存储量log @'n07 5)h  
print u'name信息:%s' % attribute_columns.get('name') w]L^)_'Th  
self.render('user.html',power=attribute_columns.get('power'),name=name)      #通过tornado的render传值到html页面进行渲染 8R|!$P  
ls[0X82F  
4.快速记 A1>fNilC9  
g{PEplk  
name = self.get_secure_cookie("test") ]q^6az(Ud  
title = self.get_argument("title", None) @7S* ]  
content = self.get_argument("content", None)      #得到POST提交过来的数据 F(h jP  
modate = time.strftime('%g%m%d-%T',time.localtime(time.time()))      #获取当前时间作为主键 EPeKg{w  
primary_key = {'modate':modate,'joter':name}      #主键值 rnAQwm-8O%  
attribute_columns = {'status':0,'type':'text','title':title,'content':content}      #传入的属性值,可变 1N\/61+aA  
condition = Condition('EXPECT_NOT_EXIST')      #判断的条件 b5i ehoA  
consumed = ots_client.put_row('alijot_user', condition, primary_key, attribute_columns)      #执行插入一条记录 lo!^h]iE!  
,J;Cb}  
KXrZ:4bg  
5.读取记录 f4'WT  
?iXN..6x  
columns_to_get = ['title', 'content']     #主键 c'|](vOd]  
inclusive_start_primary_key = {'joter':name, 'modate':INF_MIN }      #开始条件 6W\G i>  
exclusive_end_primary_key = {'joter':name, 'modate':INF_MAX }       #结束条件 z] +&kNm  
columns_to_get = ['title', 'content','modate']          # 如果需要获得文档中描述的返回列表,可以留空,或把主属性也传入 '`s+e#rs4{  
consumed, next_start_primary_key, row_list = ots_client.get_range(      #这里就是按照范围查询了 7q%xF#mK=  
  'alijot_modify', 'FORWARD',      #控制查询的方向,倒序显示:改成BACKWARD,颠倒开始和结束条件INF_MIN/INF_MAX ) kMF~S|H  
  inclusive_start_primary_key, exclusive_end_primary_key, l+nT$IPF  
  columns_to_get, 100              #100是限制的条数,不填为全部获取 NH aY&\  
) Q{[l1:  
self.render("modify.html", row_list = row_list)     #传给前端去渲染 TJ_Wze-lQ  
/7N&4FrG  
%_@T'!]  
6.删除记录 Lv&9s  
删除很简单,依旧是看DOCUMENT,最后的话,写完整的函数实现吧(tornado) 3N[Rrxe2  
O!G!Gq&  
class DelModifyHandler(tornado.web.RequestHandler): 38mC+%iC  
    def post(self):           #通过POST方式得到 W1Vy5V|M  
        name  = self.get_secure_cookie("alijot_user")       #通过cookie获取当前用户(分片键--自定的一个主键列) ^UCH+C yl  
        modate = self.get_argument("modate", None)      #得到POST过来的数据(另一个主键列) 9Iu"DOxX%  
        primary_key = {'joter':name,'modate':modate}         #这是主键 bWgRGJqt  
        condition = Condition('IGNORE')        #条件 0%<OwA2d  
        ots_client.delete_row('alijot_modify', condition, primary_key)       #然后就是执行SDK函数 xx@[ecW  
        self.redirect("/modify")          #这个是tornado跳转,回到记录页面 =Y-.=}jp;  
\,xa_zeO  
S6g_$ Q7  
P$x9Z3d_  
至此,很简陋的功能就完成了   S]&:R)#@  
"Zfm4Nx "  
KKq%'y)u^  
  • 总结:
O dbXna  
尝试过程中,遇到了几个小问题,应该属于初学者都会犯的错误。在解决了这几个问题后项目的基本功能走通后,瞬间有了种收获颇丰的赶脚,嘿嘿。而关于吞吐量的分配,后期需要仔细考虑,至于上传图片,前端JS效果,找回密码,用户设置,第三方登录 等功能还有待开发。 h/Yxm2  
近期自己实习所在的公司正在赶着上线产品以及上线维护,所以个人时间不多。我觉得既然技术还不到家,心思还是得放在工作上的,不过后期我还会不断完善,希望未来某天这个项目原型能够真正成长起来。 < 1%}8t"  
7gcR/HNeF  
;f~fGsH}e'  
----------------------------------------------------------------------------------------------------------------------------------------------------------- 9W0*|!tQ,+  
  • OTS资料整理:
)@ofczl6  
OTS介绍页面:http://www.aliyun.com/product/ots/?spm=5176.383715.3.5.F6qwY2&utm_content=m_199 0xx4rp H  
进入 OTS介绍页面在最下方的可以找到 产品帮助” 分类,可看到“OTS产品文档”。个人认为只用看 “资料中心” 分类下的资料以及SDK中的DOCUMENT即可快速上手。 "}"/d(  
A`#?Bj   
h'HI92; [  
?7]G )8G6  
----------------------------------------------------------------------------------------------------------------------------------------------------------- 3G[|4v?[<_  
alijot.com 快速记 尚处于测试开发阶段,各种功能有待完善,欢迎大家试玩,公网地址是 115.28.47.91:8888 iZLy#5(St  
欢迎大家给我投上宝贵的一票 (选票可修改,可多选) 以下是我的测评文章的投票地址: 1>uAVPa  
H $ %F0'0  
;mYZ@g%e  
编号26 http://bbs.aliyun.com/read/179696.html cQ]c!G|a4  
编号39 http://bbs.aliyun.com/read/180418.html 2-DG6\QX|  
:%z#s  
E~#G_opQA  
soLW'8  
i\_LLXc  
Do77V5  
Qd~z<U l  
gs3c1Qa3b  
3"zPG~fY{  
tfe]=_U  
^.R!sQ  
$OG){'X  
4 ob?M:S  
nw\C+1F  
2*<Zc|uNW  
4#}aLP  
(6B;  
KJV8y"^=Q  
!qp$Xtf+  
!(7m/R  
V'e%%&g~N  
_?:jZ1wZ  
:o' |%JE  
"b~C/-W I  
Pc*lHoVL  
Ovc9x\N  
[ 此帖被morenocjm在2014-10-28 23:00重新编辑 ]
本帖最近评分记录: 2 条评分 云币 +26
啊里新人 云币 +6 你懂的! 2014-10-28
qiujin2012 云币 +20 支持他,就给他投票,猛戳: http://bbs.aliyun.com/read/178799.html 2014-10-27
级别: 菜鸟
发帖
52
云币
192
只看该作者 沙发  发表于: 2014-10-26
这里有个地方希望OTS优化
在OTS“基本信息”页面中,“主键”显示的值按字母表顺序从左往右排序,所以就可能分片键在后面。而且,页面上并没有标识哪个主键是分片键,无法直观区分,希望能优化 T/g\v?>  
本帖最近评分记录: 1 条评分 云币 +5
qiujin2012 云币 +5 感谢建议,已反馈给OTS的产品经理 2014-10-27
发帖
994
云币
1363
只看该作者 板凳  发表于: 2014-10-27
支持他,就给他投票,猛戳: U=G49 ~E  
http://bbs.aliyun.com/read/178799.html
〉〉论坛经验-《阿里云服务器从入门到精通》精华汇总
http://bbs.aliyun.com/read/135619.html?amp;displayMode=1#tpc
级别: 研究猿
发帖
3357
云币
4596

只看该作者 地板  发表于: 2014-10-27
请问这个有最新的文档了么,看到的文档说的是明年2月份下线。上新版
级别: 菜鸟
发帖
52
云币
192
只看该作者 4楼 发表于: 2014-10-27
Re【阿里云产品公测】OTS使用之简单线上产品实践基于PythonSDK
文档我还真没关注版本,既然还在,那就是能用的,原谅我还是新手
本帖最近评分记录: 1 条评分 云币 +3
啊里新人 云币 +3 您的无私奉献精神值得我们学习!向您致敬! 2014-10-28
级别: 菜鸟
发帖
52
云币
192
只看该作者 5楼 发表于: 2014-10-28
Re【阿里云产品公测】OTS使用之简单线上产品实践基于PythonSDK
本帖最近评分记录: 1 条评分 云币 +1
啊里新人 云币 +1 你懂的! 2014-10-29
级别: 研究猿
发帖
3357
云币
4596

只看该作者 6楼 发表于: 2014-10-29
你懂的!
级别: 小白
发帖
4
云币
9
只看该作者 7楼 发表于: 2014-11-03
Re【阿里云产品公测】OTS使用之简单线上产品实践基于PythonSDK
Top!
级别: 架构狮
发帖
1438
云币
1888

只看该作者 8楼 发表于: 2014-11-13
级别: 小白
发帖
11
云币
8
只看该作者 9楼 发表于: 2014-11-21
Re【阿里云产品公测】OTS使用之简单线上产品实践基于PythonSDK
学习了,看得人晕
级别: 小白
发帖
11
云币
8
只看该作者 10楼 发表于: 2014-11-21
Re【阿里云产品公测】OTS使用之简单线上产品实践基于PythonSDK
大家都在学习,看到代码不容易哟
级别: 小白
发帖
11
云币
8
只看该作者 11楼 发表于: 2014-11-21
Re【阿里云产品公测】OTS使用之简单线上产品实践基于PythonSDK
谢谢阿里提供的平台,学习了
发表主题 回复主题
« 返回列表上一主题下一主题

限100 字节
批量上传需要先选择文件,再选择上传
 
验证问题: 29 + 53 = ?
上一个 下一个
      ×
      全新阿里云开发者社区, 去探索开发者的新世界吧!
      一站式的体验,更多的精彩!
      通过下面领域大门,一起探索新的技术世界吧~ (点击图标进入)