«

怎么用Python编写一个简单的缓存系统

时间:2024-6-11 13:49     作者:韩俊     分类: Python


这篇“怎么用Python编写一个简单的缓存系统”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么用Python编写一个简单的缓存系统”文章吧。

    本篇文章所依赖的

    python
    环境为:

    项目展示

    demo
    将分为2个部分展示,第一个部分我们会写入一些
    key
    value
    进入到缓存系统中,而后关闭程序。

    第二部分则会去获取第一个部分写入的

    key
    的名称。

    第一部分

    main
    方法如下:

    def main() -> None:
        c = dbCache("db.cache")
        c.cacheSetting(queueMaxKeys=3,ageSec=3)
        c.set("name","pdudo")
        c.set("site","juejin")
        c.set("hello","word")
        c.set("hello","pdudo")

    其中,

    dbCache
    是我们定义的类,而
    set
    是写入方法,
    cacheSetting
    设置一些基础环境变量,例如:

      queueMaxKeys
      : 需要制定增删改缓存队列,类型为
      int
      ,如果满了,则立即落地到磁盘中。

      ageSec
      : 间隔时间,参数为秒数,若操作第一个
      key
      和操作第二个
      key
      时间大于该设置,则落地到磁盘。

    set
    则是写入方法,参数为
    key
    value

    运行后,代码效果如下:

    由于我们只有

    set
    ,所以不会输出任何信息,上述
    open file error
    是正常的警告信息,不用管它。

    第一部分操作完毕了,我们可以修改第二部分,使用

    get
    去获取第一次存储的数据。

    修改

    main
    如下:

    def main() -> None:
        c = dbCache("db.cache")
        c.cacheSetting(queueMaxKeys=3,ageSec=3)
        print(c.get("name"))
        print(c.get("hello"))
        print(c.get("site"))

    运行后,效果如下:

    由此可以验证,从磁盘读取文件并且加载进内存,没什么问题。

    除此之外,该库还支持其他操作,例如:

    # 定义一个缓存对象
    c = dbCache("db.cache")
    # 配置环境变量
    c.cacheSetting(queueMaxKeys=3,ageSec=3)
    # 写
    c.set("name","pdudo")
    # 读
    print(c.get("name"))
    # 修改
    c.update("name", "juejin")
    # 删除
    c.delete("name")

    接下来,我们就来看下,如何一步一步完成这个最简单的缓存系统。

    不用落地的缓存系统系统应该如何实现

    python
    中,给我们提供了很多基础的数据类型,例如 列表、字典等。所以说,就没必要自己在定义一套属于自己的数据类型了,可以直接使用现有的数据类型,例如本篇文章所使用的就是字典,这里简单的铺垫一下字典的增删改查。

    铺垫python字典基本操作

    定义一个空的字典

    a
    ,可以使用如下代码:

    a = {}

    写入

    key
    可以直接使用
    a[key] = value
    即可,例如:

    a["name"] = "pdudo"

    修改也是和上述一样的

    关于查询,我们直接使用

    a[key]
    即可。

    若没有这个

    key
    会抛错:
    KeyError: 'key'

    print(a["name"])

    检查是否存在

    key
    ,可以使用
    key in dict
    来判断,例如: 想判断
    name
    是否是字典
    a
    中的
    key
    ,可以写为:

    print("name" in a)

    若存在于

    a
    中,会返回
    True
    ,否则会返回
    False

    定义一个不用落地的缓存系统

    有了上述关于字典的基本操作,我们可以将其封装一下,定义为自己的操作方法,例如:

    class cacheDB():
        def __init__(self):
            #定义空的字典
            self.cache = {}
            
        #增
        def set(self,key,value):
            self.cache[key] = value
            
        #查
        def get(self,key):
            return self.cache[key]
            
        #修
        def update(self,key,value):
            self.cache[key] = value
            
       #删除
       def delete(self,key):
           del self.cache[key]
           
    def main():
        c = cacheDB()
        c. set("name","pdudo")
        print(c.get("name"))
        c.update("name","juejin")
        print(c.get("name"))
        c.delete("name")
        
    if __name__ == '__main__':
        main()

    我们可以将上述方法,封装在一个

    class
    中,从而实现调用。

    例如,运行之后结果为:

    数据如何落地

    上述,我们已经写了一个最简单的缓存系统,如果此时进程挂掉了,重新启动后,内存中的数据就都没了,所以为了避免重启后数据丢失,可以将数据定时落地到磁盘中,本篇文章所介绍的内置库为:

    pickle
    ,该可可以将
    python
    对象存储到文件中,从而保存到磁盘,这个对象可以是字典、也可以是列表,我们来看下,具体方法:

    将对象保存到磁盘

    使用

    pickle
    dump
    方法,可以将对象保持到文件中,这里举一个很简单的例子:

    import pickle
    
    list1 = ["name","juejin","hello"]
    
    with open("test.txt","wb") as f:
        pickle.dump(list1,f)

    上述代码,先引入了

    pickle
    库,而后定义了列表
    list1
    ,最后打开文件,使用
    pickle.dump
    将列表对象保持到文件中,这里保存的是二进制,所以是
    wb
    模式。使用
    with...open
    方法,它可以主动在最后帮我们关闭文件句柄。

    此时如我们执行脚本后,想查看一下文件,会发现是二进制格式的,例如:

    将对象从磁盘中导入到内存中

    上述,我们已经将对象保持到磁盘中,接下来,我们使用

    pickle
    load
    方法,将磁盘数据导入到内存中来,这里同样举一个很简答的例子:

    import pickle
    
    with open("test.txt","rb") as f:
        list2 = pickle.load(f)
    
    print(list2)

    上述代码,还是先引入

    pickle
    库,而后在以二进制的模式读取文件,最后通过
    pickle.load
    方法,将数据从磁盘中导入到
    list2
    下,接着输出
    list2
    的值。

    运行后,可以发现,该值就是我们上述落地到磁盘的对象:

    将数据落地和缓存系统结合起来

    我们已经将数据落地测试完毕了,如何和缓存系统结合起来呢? 很简单,我们仅需要在程序启动时,检测一下是否有该文件,若有,则直接读取数据再并入到对象中,否则创建一个新的字典就好。

    而后每次有增删改操作,都将数据落地即可,这里用新增数据函数举个例子:

    class cacheDB():
        def __init__(self):
            try:
                with open("db.cache","rb") as f:
                    self.cache = pickle.load(f)
            except Exception as e:
                self.cache = {}
    
        def set(self,key,value):
            self.cache[key] = value
            with open("db.cache","wb") as f:
                pickle.dump(self.cache,f)

    上述在

    cacheDB
    __init__
    函数中,就尝试读取本地文件
    db.cache
    ,若存在,就
    load
    到内存中,若不存在,就创建一个新的字典。

    这样的话,存储的数据就不会因为程序重启而丢失了。

    如何保证并发安全

    作为一个服务对开提供访问时,需要注意一下并发安全,当多个函数对一个变量进行操作的时候,很容易引起数据混乱,所以还是有必要加一下锁的,我们可以引入

    threading
    库来完成加锁解锁操作,其加锁和解锁代码如下:

    import threading
    
    lock = threading.Lock # 定义lock
    lock.acquire() # 加锁
    lock.release() # 释放锁

    我们可以将次引入到代码中,例如:

    import pickle
    import threading
    
    lock = threading.lock
    class cacheDB():
        def __init__(self):
            try:
                with open("db.cache","rb") as f:
                    self.cache = pickle.load(f)
            except Exception as e:
                self.cache={}
                
        def set(self,key,value):
            lock.acquire()
            self.cache[key] = value
            with open("db.cache","wb") as f:
                pickle.dump(self.cache,f)
            lock.release()
            
    def main():
        db = cacheDB()
        
    if __name__ == '__main__':
        main()

    标签: python

    热门推荐