OPT(erlang)打造一套缓存系统(一)

2024-01-16 01:52

本文主要是介绍OPT(erlang)打造一套缓存系统(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

缓存的设计

这个简易缓存存储的是键/值对,其中键与键之间不得重复,并且每个键只能映射到一个值。这个设计背后的核心思想是为写人缓存的每一个值都分配一个独立的存储进程再将对应的键映射至该进程。你可能会对这种为每个值分配一个进程的设计感到惊讶,甚至觉得不可思议;但对缓存这类服务而言,这个设计是合理的,因为缓存中的值相互独立,各有各的生命周期。同时,Erlang本身对大量轻量级进程提供了良好的支持,使得这种设计成为可能。
为了搭建这个缓存,我们得先建立一些基本的子系统,其中每个子系统都是一个独立的模块。

我们一共需要创建5个模块,
用户只能通过simple_cache API模块与缓存服务交互。该模块直接与sc_store模块和sc_element模块通信,前者负责维护键和进程间的映射关系,后者负责存储进程的创建、更新和删除。所有存储进程都受sc_sup监督进程监督,除此之外,还有一个负责整个缓存系统的启动和停止的应用行为模式模块sc_app。让我们从进程和数据流的角度展示了该架构。

在处理运行时的键/值对插入操作时,监督进程会按需派生sc_element进程。派生出来的进程会记住与给定的键相关联的值,随后,sc_store会记录下该键与该进程ID间的映射关系。键/值之间的映射关系就这样建立起来了。要获取与指定的键相关联的值,首先应该查找与键相关联的存储进程的D,然后再向该进程查询当前持有的值便可。
 

创建OTP应用的基本骨架

1.应用目录结构的布局

首先新建一个名为simple_cache的顶层应用目录。在该目录下,新建doc、ebin、include、priv和src等子目录。

2.创建应用元数据

在启动应用或在执行运行时代码热升级时,OTP需要了解一些用于描述应用自身的元数据。存放元数据的.app文件的文件名应该与应用名相匹配(但无须采用特定模块的名字),在这个例子中,该文件就是ebin/simple_cache.app。

.app文件当前内容如下

{application,simple_cache,
[fdescription,"A simple caching system"},
{vsn, "0.1.0"},
{modules,[sc_app,sc_sup]},{registered,[sc_sup] } ,
{applications,[kernel, stdlib]},
{mod, {sc_app. []}}
]}.

3.实现应用行为模式

应用行为模式的实现位于文件src/sc_app.erl内,需要注意的是,.app文件中的mod元组给出了应用行为模式模块的模块名,系统就是从这里得知应该从何处启动和停止应用的。

-module(sc_app) .
-behaviour(application).
-export ([start/2, stop/1] ) .
start(_StartType, _StartArgs)->case sc_sup:start_link()of{ ok, Pid} ->{ ok,Pid};other ->{error, other}
end.
stop(_state) ->ok.

sc_app模块唯一的任务就是在应用启动时启动根监督者,在应用停止时则什么也不用做。

4.实现监督者

根监督者在文件src/sc_sup.erl中实。我们没有给这个监督者静态指派任何永久子进程,但却可以给它动态添加任意多个同类型的临时子进程。

-module(sc_sup) .
-behaviour(supervisor) .
-export([start_link /0,start_child/2]).
-export([init/1] ).
-define(SERVER,?MODULE).
start_link()->supervisor:start_link({local,?SERVER},?MODULE,[]).
start_child (Value,LeaseTime) ->supervisor:start_child ( ?SERVER,[Value,LeaseTime]).
init([])->Element = {sc__element,{sc_element,start_link,[]},temporary, brutal_kill, worker, [sc_element]},Children = [Element] ,Restartstrategy = { simple_one_for_one,0, 1},{ok,{Restartstrategy,Children }} .
1.简易一对一监督

该监督者的监督策略被设定为simple_one_for_one(简易一对一监督)。采用one_for_one等其他重启策略时,监督者一般需要同时管理多个与自己同时启动的子进程,通常这些子进程的生命周期也与监督者相同。simple_one_for_one型监督者只能启动一种子进程,但却可以启动任意多个。它所有的子进程都是运行时动态添加的,监督者本身在启动时不会启动任何子进程。
观察代码中的监督者模块,现在却只能有一个: simple_.one_for_one型监督者的init/1必须指定一种且仅一种子进程,但子进程并不会随监督者一同启动。不过,你随时可以通过调用简化版supervisor:start_child/2函数,令监督者启动新的子进程。其他类型的监督者在动态添加子进程时,必须将完整的子进程规范传递给start_child/2。但对于simple_one_for_one型监督者而言,由于所有子进程都遵循同一套已知的子进程规范,我们只需要说一声“再来一份”就可以了。这套机制恰恰可以满足我们当前的需求。

2.监督者模块

sc_sup模块有两个API函数,启动一个新的子进程,并将value和LeaseTime参数传给子进程的人口函数(因为每个子进程的这两个参数各不相同)。将这些逻辑组织成一个API函数将更有利于模块中实现细节的封装。

调用start_child/2 API函数时,当前进程会向监督进程发送一条消息,令它以value和LeaseTime为参数调用sc_element模块的start_link函数,进而启动一个新的子进程。子进程规范中的元组

{sc_element, start_link,[]}

给定了模块名、函数名和子进程启动函数的参数,调用start_link之前,列表[value,LeaseTime]将被并人参数列表[],从而形成最终的函数调用sc_element:start_link(value,LeaseTime)。

每调用一次sc_sup:start_child/2,就会新启动一个带有自己的值和淘汰时间的sc_element进程。这就形成了一棵动态生成的监督树。

至此,一个可运行的应用骨架就搭建完毕了。你可以从Erlang shell中启动它并观察它的运作情况。当然,目前除了启动和停止应用以外你还什么都做不了,因为应用的实际功能和用户接口都还没有实现。由于采用了simple_one_for_one型监督策略,监督者在启动时不会启动任何子进程;此外,由于sc_element尚未实现,调用sc_sup:start_child/2会触发运行时错误。
 

这篇关于OPT(erlang)打造一套缓存系统(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/610949

相关文章

Windows 系统下 Nginx 的配置步骤详解

《Windows系统下Nginx的配置步骤详解》Nginx是一款功能强大的软件,在互联网领域有广泛应用,简单来说,它就像一个聪明的交通指挥员,能让网站运行得更高效、更稳定,:本文主要介绍W... 目录一、为什么要用 Nginx二、Windows 系统下 Nginx 的配置步骤1. 下载 Nginx2. 解压

如何确定哪些软件是Mac系统自带的? Mac系统内置应用查看技巧

《如何确定哪些软件是Mac系统自带的?Mac系统内置应用查看技巧》如何确定哪些软件是Mac系统自带的?mac系统中有很多自带的应用,想要看看哪些是系统自带,该怎么查看呢?下面我们就来看看Mac系统内... 在MAC电脑上,可以使用以下方法来确定哪些软件是系统自带的:1.应用程序文件夹打开应用程序文件夹

windows系统上如何进行maven安装和配置方式

《windows系统上如何进行maven安装和配置方式》:本文主要介绍windows系统上如何进行maven安装和配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录1. Maven 简介2. maven的下载与安装2.1 下载 Maven2.2 Maven安装2.

使用Python实现Windows系统垃圾清理

《使用Python实现Windows系统垃圾清理》Windows自带的磁盘清理工具功能有限,无法深度清理各类垃圾文件,所以本文为大家介绍了如何使用Python+PyQt5开发一个Windows系统垃圾... 目录一、开发背景与工具概述1.1 为什么需要专业清理工具1.2 工具设计理念二、工具核心功能解析2.

Linux系统之stress-ng测压工具的使用

《Linux系统之stress-ng测压工具的使用》:本文主要介绍Linux系统之stress-ng测压工具的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、理论1.stress工具简介与安装2.语法及参数3.具体安装二、实验1.运行8 cpu, 4 fo

Java实现本地缓存的常用方案介绍

《Java实现本地缓存的常用方案介绍》本地缓存的代表技术主要有HashMap,GuavaCache,Caffeine和Encahche,这篇文章主要来和大家聊聊java利用这些技术分别实现本地缓存的方... 目录本地缓存实现方式HashMapConcurrentHashMapGuava CacheCaffe

如何更改pycharm缓存路径和虚拟内存分页文件位置(c盘爆红)

《如何更改pycharm缓存路径和虚拟内存分页文件位置(c盘爆红)》:本文主要介绍如何更改pycharm缓存路径和虚拟内存分页文件位置(c盘爆红)问题,具有很好的参考价值,希望对大家有所帮助,如有... 目录先在你打算存放的地方建四个文件夹更改这四个路径就可以修改默认虚拟内存分页js文件的位置接下来从高级-

PyCharm如何更改缓存位置

《PyCharm如何更改缓存位置》:本文主要介绍PyCharm如何更改缓存位置的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录PyCharm更改缓存位置1.打开PyCharm的安装编程目录2.将config、sjsystem、plugins和log的路径

JSR-107缓存规范介绍

《JSR-107缓存规范介绍》JSR是JavaSpecificationRequests的缩写,意思是Java规范提案,下面给大家介绍JSR-107缓存规范的相关知识,感兴趣的朋友一起看看吧... 目录1.什么是jsR-1072.应用调用缓存图示3.JSR-107规范使用4.Spring 缓存机制缓存是每一

Spring 缓存在项目中的使用详解

《Spring缓存在项目中的使用详解》Spring缓存机制,Cache接口为缓存的组件规范定义,包扩缓存的各种操作(添加缓存、删除缓存、修改缓存等),本文给大家介绍Spring缓存在项目中的使用... 目录1.Spring 缓存机制介绍2.Spring 缓存用到的概念Ⅰ.两个接口Ⅱ.三个注解(方法层次)Ⅲ.