通过写代码学习AWS DynamoDB (2)_aws ddb-程序员宅基地

技术标签: 学习  分布式系统设计  aws  AWS  云计算  

简介

在上一篇文章里,我们实现了DDB的基本API。上一篇文章请见《通过写代码学习AWS DynamoDB(1)》。在本文中,我们将进一步增强该DDB的模拟实现,给DDB加入Partition。

Partition是Shard的一种。关于Shard的介绍可以参看这篇文章。我们简单介绍一下Shard和Parition的概念。然后我们会在DDB的实现中加上一个简单的Parition的实现。

Shard介绍

区别于传统的基于集中式环境实现数据存储,分布式系统是将数据分散的存储在多个地方,可能是不同的host,或者是server,或者是cluster,等等。每一个这样的节点就是一个shard。使用shard带来的好处有以下几点:

  • scale更加容易实现和管理:假如数据存储在一个集中的节点上,我们就要预先估计我们要使用的数据存储容量。过大会浪费很多存储,过小又会需要经常调整,非常麻烦。而且单一存储节点的容量调整本身也很麻烦,一般需要具有一定的专业知识,通过复杂的操作和指令来实现存储容量的扩容。但是有了shard这一切就变得简单和灵活很多。在需要调整数据存储容量时,我们仅仅需要增加和减少shard。
  • 系统的robust会得到加强。传统的集中存储方式,一旦存储的服务器出现问题,整个系统就会瘫痪。但是基于shard的实现,如果一个shard出现问题,系统仅仅是部分数据无法访问,整体功能仍然可以部分得到保障。如果我们将shard和replica配合使用,则可以保障整体系统的robust会更好。
  • 系统的响应时间会得到改善。不同于传统的集中式存储,数据可以根据需要存储在多个shard里。首先,多个存储本身就很有利于并行的处理数据操作,从而使得响应时间得到改善。其次,shard可以根据需要部署到和client更近的地方,从而改善响应时间。例如,如果数据是和城市有关的,那么我们可以将数据按照城市分别存到不同的shard里,并将每个城市的shard部署到该城市。

Shard的方法:

  1. Range-based sharding:通过对某一条或者几条attribute进行区间划分来决定shard。比如对于人口的数据按照年龄的分布,0到10岁存储到一个shard,10岁到20岁存储到一个shard,等。
  2. Hashed sharding:通过对key进行hash来决定该一条记录所对应的shard。
  3. Directory sharding:通过某种形式的对应来决定一条记录所对应的shard。比如存储文章,我们可以将历史类的存储在一个shard,文学类的存储在一个shard,等。
  4. Geo sharding:通过地理位置来决定shard。比如上面例子中通过城市来决定。

Partition介绍

数据库的Partition是将数据分成多个小组进行处理的一种技术。所以partition和shard基本一样的设计理念,但是不完全一样。Parition分为两种:

  • 横向partition:将数据表的行进行分组。
  • 纵向partition:将数据表的列进行分组。

事实上,两种partition都可以认为是shard在数据库中的具体实现。

在DynamoDB的模拟实现中加入Partition

首先我们先实现一个Parition类。这个Partition类可以实现CRUD的功能(也就是create,read,update,delete),同时它还提供了一个接口可以返回该partition的统计信息。具体代码如下:

class Partition:
    def __init__(self):
        self.storage = {}

    def put_item(self, key, value):
        self.storage.update({key: value})

    def get_item(self, key):
        return self.storage[key]
    
    def delete_item(self, key):
        self.storage.pop(key)

    def get_item_count(self):
        return len(self.storage.items())

我们将给DDB的table添加Parition List。在这里我们使用Hash partition。针对每一个key,我们首先计算该key的hash value,然后对partition的个数取模来确定该key应该存在在哪个partition里。并且现在Table将不再保存数据的统计信息(例如有多少条数据),因为数据已经分布到多个partition里,所以Table将通过轮询Paritition的方式来汇总Table级别的统计信息(参见Table.describe()的实现)。代码的实现如下:

import functools
from partition import Partition

# class to provide DDB public APIs
# - support partitions based on hash value of key;
class DDB:
    def __init__(self):
        self.tables = {}

    def create_table(self, table_name):
        self.tables[table_name] = self.Table(table_name)

    def list_table(self):
        for table in self.tables.values():
            table.describe()

    def delete_table(self, table_name):
        self.tables.pop(table_name)

    def get_table(self, table_name):
        return self.tables[table_name]
    
    class Table:
        def __init__(self, name, partition_count=3):
            self.name = name
            self.partitions = [Partition() for _ in range(partition_count)]
            self.partition_count = partition_count

        def put_item(self, key, value):
            print("save {} to partition {}".format(key, self.get_partition_id(key)))
            self.partitions[self.get_partition_id(key)].put_item(key, value)

        def update_item(self, key, value):
            self.partitions[self.get_partition_id(key)].put_item(key, value)

        def get_item(self, key):
            print("get {} from partition {}".format(key, self.get_partition_id(key)))
            return self.partitions[self.get_partition_id(key)].get_item(key)
        
        def delete_item(self, key):
            print("delete {} from partition {}".format(key, self.get_partition_id(key)))
            self.partitions[self.get_partition_id(key)].delete_item(key)

        def describe(self):
            item_count = functools.reduce(lambda x, y : x + y.get_item_count(), self.partitions, 0)
            print("Table name: {}, item size: {}".format(self.name, item_count))

        def get_partition_id(self, key):
            return self.my_hash(key) % self.partition_count
        
        def my_hash(self, text:str):
            hash=0
            for ch in text:
                hash = ( hash*281  ^ ord(ch)*997) & 0xFFFFFFFF
            return hash

现在我们DDB的class diagram看起来是这个样子:

显示我们修改一下我们之前的测试代码,并且看一下partition是否工作正常:

from ddb import DDB

ddb = DDB()

table_name = "test_table"
key = "test_key"
value = "test_value"

ddb.create_table(table_name)
ddb.list_table()
ddb_table = ddb.get_table(table_name)
ddb_table.put_item("1", value)
ddb_table.put_item("2", value)
ddb_table.put_item("3", value)

print(ddb_table.get_item("1"))
print(ddb_table.get_item("2"))
print(ddb_table.get_item("3"))

ddb_table.delete_item("1")

ddb_table.describe()

代码的运行结果:

Table name: test_table, item size: 0
save 1 to partition 1
save 2 to partition 2
save 3 to partition 0
get 1 from partition 1
test_value
get 2 from partition 2
test_value
get 3 from partition 0
test_value
delete 1 from partition 1
Table name: test_table, item size: 2

我们看到每条记录被正确的存储到各个partition里,并且可以正常的访问。关于整张表的统计信息,也就是表里有多少条记录也是正确的。

小结

我们的DDB已经可以将数据灵活的存储在多个partition里了。现在我们可以很容易scale out或者scale in我们的DDB。但是我们注意到如下问题:

  1. 如果partition增加,根据hash value模partition的数量来确定partition的方式就不正确了,因为一条数据对应的partition会发生改变。
  2. 我们仅仅是在存储上实现了partition,但是并没有真正实现并行的数据处理。
  3. 我们的数据库没有replica来保障数据和服务availability。

这些问题我们将在后面的文章中继续解决。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_42325834/article/details/135877562

智能推荐

爬虫实战:python 扩展库 urllib2 应用之如何自定义电影类型爬取豆瓣电影数据?-程序员宅基地

文章浏览阅读630次,点赞10次,收藏17次。识点,真正体系化!**

【软件质量保证与测试】练习1_软件测试与质量保证pta test 21-练习1-程序员宅基地

文章浏览阅读950次。主观题8-1 软件测试的价值IBM公司研究发现: 如需求分析阶段引入一个缺陷,在测试执行阶段前修改成本为1,在编码阶段后修改成本则为10,在维护阶段,修改成本则为100。在测试阶段前的每个阶段进行静态测试的缺陷消除率为50%,测试阶段的缺陷消除率为80%。 假设某项目开发过程中分别有需求、设计、编码、测试、维护 5个阶段(瀑布模型),其中在需求、设计、编码阶段各引入10个缺陷(共30个缺陷)。试计算并比较提前测试与编码后测试两种方案的缺陷修改成本。说明:缺陷消除率:指发现的缺陷数占总缺陷数的比例。_软件测试与质量保证pta test 21-练习1

(赠源码)Python+django+Mysql公交线路查询系统85021-计算机毕业设计_python查实时公交情况查询-程序员宅基地

文章浏览阅读335次,点赞4次,收藏2次。公交线路查询系统的主要使用者分为管理员、乘客用户,实现功能包括后台首页、轮播图、公告管理、资源管理(新闻列表、新闻分类列表)、交流管理(论坛列表、论坛分类列表)、系统用户(管理员、乘客用户)、模块管理(线路信息、异常通知、投诉建议)等功能。本系统的使用可以实现公交线路查询的信息化,可以方便用户查看公交路线信息等,可以大大提高管理效率。_python查实时公交情况查询

Datax DB2插件开发_datax 接入db2-程序员宅基地

文章浏览阅读1.4k次。对于datax来说, 其实所有的关系型数据库步骤都差不多, 不同的就在于不同的数据库对于SQL的要求:例如开发流程1. 新建module2.DB2配置文件处理1. 新建module2.DB2配置文件处理Datax/db2reader/src/main/resources/{json文件}: 负责生成jar包和json模板Datax/db2reader/pom.xml: 负责maven编译,配置依赖项Datax/db2reader/src/main/assembly/package.xml: _datax 接入db2

计算机专业毕设选题,java毕设选题-程序员宅基地

文章浏览阅读44次。计算机专业毕设选题,java毕设选题

STM32CubeMX使用-程序员宅基地

文章浏览阅读1.4k次。一、新建工程首先,打开,第一次使用的朋友可以点击右侧的和检查一下软件更新并且找到对应芯片的固件库然后下载,软件和固件库都推荐是使用最新版的,这里不多介绍。完毕之后点击来创建一个新的工程。在弹出的界面中找到并选择对应芯片型号,可以在左上角的对话框中搜索,选中后点击来新建工程。_stm32cubemx

随便推点

大数据岗位秋招面试八股文总结(不定时更新)_大数据面试八股文-程序员宅基地

文章浏览阅读1.3k次。第一次是局部聚合,先给每个key都打上一个随机数,比如10以内的随机数,此时原先一样的key就变成不一样的了,比如(hello, 1) (hello, 1) (hello, 1) (hello, 1),就会变成(1_hello, 1) (1_hello, 1) (2_hello, 1) (2_hello, 1)。然后将各个key的前缀给去掉,就会变成(hello,2)(hello,2),再次进行全局聚合操作,就可以得到最终结果了,比如(hello, 4)。分区表按照分区字段的值进行分割,容易产生数据倾斜。_大数据面试八股文

以得物商品列表数据为例,打造python爬虫_得物爬虫-程序员宅基地

文章浏览阅读6.9k次,点赞3次,收藏31次。原创来自本人的公众号:阿嚏个技术公众号文章地址:文章仅限学习交流所用,禁止商业用途,如有不适,请联系作者删除。1、爬虫思路其实就是解决爬什么,怎么爬的问题。爬什么好解决,一般都是看中一个网站的数据,采集到本地进行分析整理。接着就是针对需要爬的页面进行分析,页面分析的过程就是解决怎么爬的问题,包括页面请求的地址、请求的参数、返回的数据格式等,这些相关问题搞清楚了,就可以用程序模拟用户的请求去获取想要的数据。本文通过得物微信小程序分析入手,获取品牌商品列表来获取在得物上架的商品信息.._得物爬虫

【pycharm】【安装和管理Python包】_pycharm 自带的python包-程序员宅基地

文章浏览阅读866次,点赞20次,收藏7次。帮助您查看解释器中的Python包,并管理它们。你可以使用这个来查看PyCharm已经安装了哪些包,例如如果你选择Flask作为你的项目类型,一些包将会被安装,比如Jinja 2和Flask包。在Packages工具窗口中,您可以输入请求,PyCharm将搜索PyPi存储库并返回与您的搜索匹配的最相关的包。如果您现在检查已安装软件包的列表,请求就在那里,准备导入并在我们的脚本中使用。在这种情况下,您需要单击三个点,然后选择删除包。要安装该软件包,您可以单击安装,这将使用该软件包的最新稳定版本。_pycharm 自带的python包

IE 10以上HTML css兼容问题,前端开发中的兼容性问题-CSS篇-程序员宅基地

文章浏览阅读944次。(一)前言浏览器兼容性问题一直都让我很头疼,网上大神们给出的解决方法也是五花八门,向后或向前兼容的说法都有,所以自己整理一下,如果有不恰当的欢迎指正!(二)CSS兼容问题的原因我觉得要解决问题,就要先找出问题的根源,所以先研究通常出现的CSS兼容问题的原因有哪些……1、浏览器内核的差异浏览器的内核是分为两个部分的,一是渲染引擎,另一个是JS引擎。现在JS引擎比较独立,内核更加倾向于说渲染引擎。由于..._ie bootstrap.min.css height兼容性

跑通yolox-s官方源码(可与yolov5s做对比试验)_yolox_s.pth-程序员宅基地

文章浏览阅读3.7k次,点赞8次,收藏37次。跑通yolox-s官方源码(可与yolov5s做对比试验)_yolox_s.pth

适用于渗透测试不同阶段的工具收集整理(转载)-程序员宅基地

文章浏览阅读1.1k次。Red Teaming / Adversary Simulation Toolkit该资源清单列表涵盖了一系列,适用于渗透测试不同阶段的开源/商业工具。如果你想为此列表添加贡献,欢迎你向我发送pull requestGithub:github.com/Snowming04内容侦察武器化交货命令与控制横向运动建立立足点升级特权数据泄露杂项参考侦察主动情报收集Ey..._gophish获取cookie