并发 并行的区别?

并发:
   在一个时间段内,多任务同时运行
并行:
   在一个时间点上,多任务同时运行, 多核CPU

高并发问题

一、多进程
   把每个任务,都分配给一个进程,由操作系统内核,对进程进行调度
优点:

由于进程是资源独立的,每个任务的资源不会出现抢占资源的问题,代码维护非常方便

缺点:

进程的资源消耗要比较大 资源切换时间

进程的切换也需要消耗系统时间 调度时间

二、多线程
优点:

资源的切换不需要时间,共享进程的

缺点:

切换也需要消耗系统时间

资源共享,互斥问题,代码书写上考虑临界资源的问题

引入锁

  • 读锁
  • 写锁
系统消耗时间分为
  • CPU密集型
  • 运算多
  • IO密集型
  • 借助硬件进行数据的读写操作
在python中线程:

   线程 GIL 全局解释器锁
   不适合CPU密集型
   适合IO密集型,多线程爬虫

redis持久化:

hiredis异步链接 redis 异步_并行与并发

  • RDB
    把内存中的数据,以镜像形式保存在硬盘上
    配置:
    save N M 在N秒内,有M次操作时,触发RDB的持久化
    特点:
    容易丢失数据
    方案:
    linux一个fork技术,产生一个新的子进程,进行持久化 ,写时拷贝技术
  • AOF
    把所有写redis的命令,以日志形式追加到持久化文件中
redis的数据一致性问题:

解决方案:
   1. redis k-v对都有过期时间
   2. 当后台管理页面,api接口 一旦有写入操作,就删除数据库的内容重新写入

阻塞IO模型:
  • 阻塞IO模型
    当发起一个请求(读、写)给了硬件,如果条件不满足,把当前线程切换为等待态一旦条件满足,才被唤醒
    此时线程的后续代码,不会被执行,只有等待前序代码执行完成才能执行。
非阻塞模型
  • 非阻塞IO模型
    当发起一个请求(读、写)给了硬件,如果条件不满足,立刻从内核中返回,回到用户空间处client.setblocking(False),由于条件不满足,并没有等待条件的过程,而CPU运行时间非常的快,导致慢速IO还没有数据到来,程序就已经被CPU运行到数据处理部分

采用轮询方式,来知道慢速IO是否有数据到来

  • 多路IO进行统一的事件监听管理 (异步模型)
    异步编程的特性:
  1. 事件注册机制
    向整个异步模型中提供的事件表中注册事件发生后的处理方案
  2. 死循环等待事件的发生(loopevent)
    事件循环+回调机制的一种编程方式

把所有可能阻塞的IO处理部分,都分离成一个个回调函数
把这些回调函数注册到对应的事件上

主循环中,利用操作系统提供的监听机制,等待事件触发
一旦有事件到来,操作系统会返回对应事件的对象

从这个对象中,取出处理函数名,进行执行

redis 签到

保存在哪里,以什么格式进行维护,连续签到,如果中断签到,重新开始
在redis中,使用hash结构进行每个用户的签到数据维护

key的取值:
   sign_用户ID号
value的取值:
 哈希结构
   date: 最近签到日期字符串
   state: 签到次数
首次签到
   hget获取不到值,说明首次
   hset
正常的次日签到
   当前天数 - date天数 <= 1

断签后的签到
   当前天数 - date天数 > 1

bitmap签到技术的思路

  • 设计思路
    对于用户签到数据,如果每条数据都用K/V的方式存储,当用户量大的时候内存开销是非常大的。
    而位图(BitMap)是由一组bit位组成的,每个bit位对应0和1两个状态,虽然内部还是采用String类型存储,但Redis提供了一些指令用于直接操作位图,可以把它看作是一个bit数组,数组的下标就是偏移量。
    它的优点是内存开销小、效率高且操作简单,很适合用于签到场景。

Redis提供了以下几个指令用于操作位图:

  • SETBIT
  • GETBIT
  • BITCOUNT
  • BITPOS
  • BITOP
  • BITFIELD

特点:

  1. 节约空间
  2. 大量数据排序
    外排序:指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的。
    归并排序:将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 采用分而治之法