zoukankan      html  css  js  c++  java
  • DAY 130 redis实现分布式锁

    1 分布式锁,使用redis实现分布式锁

    1 分布式系统中,为了保证数据的最终一致性

    2 具备特性
       在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行;
       高可用的获取锁与释放锁;
       高性能的获取锁与释放锁;
       具备可重入特性;
       具备锁失效机制,防止死锁;
       具备非阻塞锁特性,即没有获取到锁将直接返回获取锁失败
       
    3 分布式锁实现
       基于数据库实现分布式锁----》悲观---》效率很低
       基于缓存(Redis等)实现分布式锁---》效率高
       基于Zookeeper实现分布式锁---
       
    4 源码安装第三方包
    -下载
       -执行 python3 setup.py install

     

    import redis

    import uuid
    import time
    from threading import Thread
    #连接redis
    redis_client = redis.Redis(host="localhost",
                              port=6379,
                              password='',
                              db=10)

    #获取一个锁
    # lock_name:锁定名称
    # acquire_time: 客户端等待获取锁的时间
    # time_out: 锁的超时时间
    def acquire_lock(lock_name, acquire_time=10, time_out=10):
       """获取一个分布式锁"""
       identifier = str(uuid.uuid4())
       end = time.time() + acquire_time
       lock = "string:lock:" + lock_name
       while time.time() < end:
           if redis_client.setnx(lock, identifier):
               # 给锁设置超时时间, 防止进程崩溃导致其他进程无法获取锁
               redis_client.expire(lock, time_out)
               return identifier
           elif not redis_client.ttl(lock):
               redis_client.expire(lock, time_out)
           time.sleep(0.001)
       return False

    #释放一个锁
    def release_lock(lock_name, identifier):
       """通用的锁释放函数"""
       lock = "string:lock:" + lock_name
       pip = redis_client.pipeline(True)
       while True:
           try:
               pip.watch(lock)
               lock_value = redis_client.get(lock)
               if not lock_value:
                   return True

               if lock_value.decode() == identifier:
                   pip.multi()
                   pip.delete(lock)
                   pip.execute()
                   return True
               pip.unwatch()
               break
           except redis.excetions.WacthcError:
               pass
       return False



    # def seckill():
    #     identifier=acquire_lock('resource')
    #     print(Thread.getName(),"获得了锁")
    #     release_lock('resource',identifier)
    #
    # if __name__ == '__main__':
    #
    #     for i in range(50):
    #         t = Thread(target=seckill)
    #         t.start()

    from redlock import Redlock
    dlm = Redlock([{"host": "localhost", "port": 6379, "db": 0}, ])

    def seckill():
       identifier=dlm.lock('order_01',1000)
       print(Thread.getName(),"获得了锁")
       dlm.unlock(identifier)

    if __name__ == '__main__':
       for i in range(50):
           t = Thread(target=seckill)
           t.start()

     

    2 分布式id生成方案

    1 分布式id,在分布式的系统中,生成全局唯一的id号
    2 要求
    1 全局唯一性:不能出现重复的ID号
    2 趋势递增:保证存到数据库速度和查询速度
    3 单调递增:保证下一个ID一定大于上一个ID
    4 信息安全:如果ID是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定URL即可;
       
    3 qps  tps
    QPS:Queries Per Second意思是“每秒查询率”,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。
    TPS:是TransactionsPerSecond的缩写,也就是事务数/秒。它是软件测试结果的测量单位。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数


    4 生成方案
    -数据库自增:性能低
       -uuid:没有趋势递增,可能会重复
       -redis生成:日期+当日自增长号
       -snowflake:雪花算法
      -64-bit
           -snowflake方案的QPS约为409.6w/s
           -python实现
           -go写的,dll,放到项目中调用

     

    3 paramiko模块

    0 paramiko ,sbuprocess,psutil
    1 用于帮助开发者通过代码远程连接服务器,并对服务器进行操作

    http://www.liuqingzheng.top/python/%E5%85%B6%E4%BB%96/03-paramiko%E6%A8%A1%E5%9D%97%E7%9A%84%E4%BD%BF%E7%94%A8/

     

    5 IO模型

    c10k问题
    http://www.liuqingzheng.top/python/Python%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/25-IO%E6%A8%A1%E5%9E%8B/


  • 相关阅读:
    【HDOJ5538】House Building(计算几何)
    maven操作
    Guava 是个风火轮之函数式编程(3)——表处理
    guava 学习笔记 使用瓜娃(guava)的选择和预判断使代码变得简洁
    guava 学习笔记(二) 瓜娃(guava)的API快速熟悉使用
    Google Guava官方教程(中文版)
    Guava中Predicate的常见用法
    guava函数式编程
    idea常用快捷键
    guava
  • 原文地址:https://www.cnblogs.com/DEJAVU888/p/14957190.html
Copyright © 2011-2022 走看看