V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
smallgoogle
V2EX  ›  Python

一个业务逻辑实现思路想问问大家

  •  
  •   smallgoogle · Sep 16, 2019 · 5384 views
    This topic created in 2417 days ago, the information mentioned may be changed or developed.

    我当前是使用 queue 单向队列;

    我需要实现功能如下:
    从数据库拉取数据,然后放入队列,然后多线程进行访问;
    线程每次使用 queue.get 获取一条数据访问;结束业务的时候又把数据 put 到队尾;
    一直循环;

    我另外还有一个线程,一直监听一个接收事件,如果接收到数据,就往队列里插入数据;
    那么问题来了,如果我想中间的时候往队列里增加数据 或者 删除数据怎么办? 比如我想删除队列里的某一个数据,好像 queue 不支持从中间删除数据。
    我这样的业务逻辑是不是不应该使用队列?

    Supplement 1  ·  Sep 17, 2019
    我的原始业务逻辑大概是:
    我想有一个数组 或者 队列 一样存放数据的地方,我不想每次都查询数据库,所以把数据拉出来就放在这里面,暂且称之为 [池] ;
    我要从池里拉取 url 进行访问,如果访问正常,则从新插到池最后,否则就丢弃,
    然后我是多线程的,我害怕线程会取到同一条数据,所以用了队列的方式,毕竟 queue.get 可以避免线程取到同一条数据;

    并且我有一个 redis 订阅,如果 redis 有新的数据了,我就把新的数据放入池里;

    其实最终我并不是想用队列来实现,只是害怕线程会取到同样的数据,我才用了队列;
    可是我发现队列并不能满足我的业务需求,比如往队列里删除指定数据;
    所以各位,有什么高见;
    27 replies    2019-09-19 09:52:10 +08:00
    Amit
        1
    Amit  
       Sep 16, 2019
    这里没看出来哪里一定需要队列,queue.get 每次获取一条数据,数据还有插入删除的操作,不如直接使用数据库实现一个链表,定时任务每次查询一条头部记录
    smallgoogle
        2
    smallgoogle  
    OP
       Sep 16, 2019
    @Amit 因为不想每次都从数据库里拉数据,想第一次启动的时候就拉出数据放在队列,然后利用队列会锁住数据的功能,让多线程不会执行到同一条数据。
    speedofstephen
        3
    speedofstephen  
       Sep 16, 2019
    额 linkedlist 其实实现了 Queue
    xstoop
        4
    xstoop  
       Sep 16, 2019
    感觉你的队列使用有问题,一般队列的消费者跟生产者是分开的
    Lax
        5
    Lax  
       Sep 16, 2019
    “队列会锁住数据” ???这是个什么原理
    smallgoogle
        6
    smallgoogle  
    OP
       Sep 16, 2019
    @xstoop 我认为我使用队列是有问题的,但是应该使用啥,我就是不知道 = =
    smallgoogle
        7
    smallgoogle  
    OP
       Sep 16, 2019
    @Lax 我想表达的是,我多线程的时候,他们不会取到同一条数据的意思。 = =
    workspace
        8
    workspace  
       Sep 16, 2019
    关键字 redis list pop
    workspace
        9
    workspace  
       Sep 16, 2019
    另外可看下最近基于 redis 实现的一个简单队列: https://github.com/lgphone/delay-queue
    tt67wq
        10
    tt67wq  
       Sep 16, 2019
    redis zset 可以的,用分数来维持顺序
    xstoop
        11
    xstoop  
       Sep 16, 2019
    @smallgoogle 抛开你说的队列,线程这些。你大概描述一下你要实现的业务需求是什么呢
    raysonlu
        12
    raysonlu  
       Sep 16, 2019
    有点好奇你的业务,消费者每次消费完毕,都放回队列,然后又有一个生产者往队列塞东西,最后这个队列岂不是越滚越大? BTW,插队这种不恶劣行为估计是做不了的,删除的话,你可以再维护一个删除名单表让每次消费队列的时候都查询一下。zset 可以维持顺序,但消费者只能是定时任务中运行了。
    alexzhu592
        13
    alexzhu592  
       Sep 16, 2019 via Android
    @Lax 他应该是说的是阻塞
    alexzhu592
        14
    alexzhu592  
       Sep 16, 2019 via Android
    你的业务不适合用队列,想其他办法吧
    hspeed18
        15
    hspeed18  
       Sep 17, 2019   ❤️ 1
    为什么不说一下你的业务需求是什么,用队列的理由是什么?
    ziding
        16
    ziding  
       Sep 17, 2019
    感觉你是用错了,如果有任务优先级的要求,你应该用优先队列,而不是普通队列。如果用普通队列,要求能够撤回某些消息,应该用业务补偿,回滚的方式进行处理,而不是中间取消掉某个任务。
    hellotime
        17
    hellotime  
       Sep 17, 2019
    还是抛出原始需求比较好
    smallgoogle
        18
    smallgoogle  
    OP
       Sep 17, 2019
    @hspeed18
    @hellotime
    @alexzhu592
    @raysonlu
    @xstoop
    从看一下帖子不,我更了一下原始需求,给点高见;
    raysonlu
        19
    raysonlu  
       Sep 17, 2019
    像你说的,存放数据的地方,是个池或者数组,可以满足你增删需求,然后处理数据是个队列,可以满足多线程需求,那么,池归池,队列归队列,再找一个单线程的方法,让池中的数据迅速流入队列不就好了?
    hellotime
        20
    hellotime  
       Sep 17, 2019
    @smallgoogle 这哪是原始需求,你的原始需求应该类似是我想搞一个代理网站,逐个测试一下代理,如果代理不行了就遗弃,可以的就保存起来,待下次检测。原始需求指的是产品要啥功能,而不是你做为开发说你要个队列。。
    hellotime
        21
    hellotime  
       Sep 17, 2019
    多线程好像也取不到同一条记录把。
    lazyfighter
        22
    lazyfighter  
       Sep 17, 2019
    你应该说需求,另外这样使用队列,不会 oom 吗
    movax21h
        23
    movax21h  
       Sep 17, 2019
    应该不需要列队吧?
    因为你的多线程其实根本不会对同一个数据进行读写操作。(没有这个业务需求)

    简单点,如果有 4 个线程,把从数据库获取的 url,分成四份不就行了吗?
    最后处理完成之后,再合一起。

    不要打架,好处都有啥。
    Zzzz07
        24
    Zzzz07  
       Sep 17, 2019
    我也有个类似的需求,当有新的数据加入时就删除队列,出队时队列为空就重新去数据库中查询添加到队列中
    alexzhu592
        25
    alexzhu592  
       Sep 17, 2019
    其实你的需求就是要保证容器的并发安全,同时又增删操作,主要是查询,你就直接用 redis 就可以了
    jimrok
        26
    jimrok  
       Sep 17, 2019
    感觉是一个做爬虫的小白
    jiangbingo
        27
    jiangbingo  
       Sep 19, 2019
    K:V 映射的字典 pop 出 K-url,update V-数据 会有什么问题?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3782 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 89ms · UTC 10:30 · PVG 18:30 · LAX 03:30 · JFK 06:30
    ♥ Do have faith in what you're doing.