在Python的gevent框架下执行异步的Solr查询的教程

yipeiwu_com6年前Python基础

 我经常需要用Python与solr进行异步请求工作。这里有段代码阻塞在Solr http请求上, 直到第一个完成才会执行第二个请求,代码如下:
 

import requests
 
#Search 1
solrResp = requests.get('http://mysolr.com/solr/statedecoded/search?q=law')
 
for doc in solrResp.json()['response']['docs']:
  print doc['catch_line']
 
#Search 2
solrResp = requests.get('http://mysolr.com/solr/statedecoded/search?q=shoplifting')
 
for doc in solrResp.json()['response']['docs']:
  print doc['catch_line']

(我们用Requests库进行http请求)

通过脚本把文档索引到Solr, 进而可以并行工作是很好的。我需要扩展我的工作,因此索引瓶颈是Solr,而不是网络请求。


不幸的是,当进行异步编程时python不像Javascript或Go那样方便。但是,gevent库能给我们带来些帮助。gevent底层用的是libevent库,构建于原生异步调用(select, poll等原始异步调用),libevent很好的协调很多低层的异步功能。

使用gevent很简单,让人纠结的一点就是thegevent.monkey.patch_all(), 为更好的与gevent的异步协作,它修补了很多标准库。听起来很恐怖,但是我还没有在使用这个补丁实现时遇到 问题。


事不宜迟,下面就是你如果用gevents来并行Solr请求:
 

import requests
from gevent import monkey
import gevent
monkey.patch_all()
 
 
class Searcher(object):
  """ Simple wrapper for doing a search and collecting the
    results """
  def __init__(self, searchUrl):
    self.searchUrl = searchUrl
 
  def search(self):
    solrResp = requests.get(self.searchUrl)
    self.docs = solrResp.json()['response']['docs']
 
 
def searchMultiple(urls):
  """ Use gevent to execute the passed in urls;
    dump the results"""
  searchers = [Searcher(url) for url in urls]
 
  # Gather a handle for each task
  handles = []
  for searcher in searchers:
    handles.append(gevent.spawn(searcher.search))
 
  # Block until all work is done
  gevent.joinall(handles)
 
  # Dump the results
  for searcher in searchers:
    print "Search Results for %s" % searcher.searchUrl
    for doc in searcher.docs:
      print doc['catch_line']
 
searchUrls = ['http://mysolr.com/solr/statedecoded/search?q=law',
       'http://mysolr.com/solr/statedecoded/search?q=shoplifting']

 
searchMultiple(searchUrls)
代码增加了,而且不如相同功能的Javascript代码简洁,但是它能完成相应的工作,代码的精髓是下面几行:
 

# Gather a handle for each task
handles = []
for searcher in searchers:
  handles.append(gevent.spawn(searcher.search))
 
# Block until all work is done
gevent.joinall(handles)

我们让gevent产生searcher.search, 我们可以对产生的任务进行操作,然后我们可以随意的等着所有产生的任务完成,最后导出结果。

差不多就这样子.如果你有任何想法请给我们留言。让我们知道我们如何能为你的Solr搜索应用提供帮助。

相关文章

python 多维切片之冒号和三个点的用法介绍

python 多维切片之冒号和三个点的用法介绍

初学python和numpy,对在学习多维切片的过程中遇到的问题做个总结。 一维切片就不说了,比较简单,先说下二维的,二维的理解了多维的就简单了。举个例子先建立一个5x5的二维数组 多...

python通过robert、sobel、Laplace算子实现图像边缘提取详解

python通过robert、sobel、Laplace算子实现图像边缘提取详解

实现思路:   1,将传进来的图片矩阵用算子进行卷积求和(卷积和取绝对值)   2,用新的矩阵(与原图一样大小)去接收每次的卷积和的值   3,卷积图片所有的像素点后,把新的矩阵数据类型...

解决python明明pip安装成功却找不到包的问题

如下所示: 原因1:版本不对,如用环境变量设置的python3.7路径,那么用的就是3.7的pip.exe安装了包。却用的是2.7的python运行 原因2:名称重复,在当前路径下有与i...

对Python中class和instance以及self的用法详解

一. Python 的类和实例 在面向对象中,最重要的概念就是类(class)和实例(instance),类是抽象的模板,而实例是根据类创建出来的一个个具体的 “对象”。 就好比,学生是...

程序员的七夕用30行代码让Python化身表白神器

程序员的七夕用30行代码让Python化身表白神器

转眼又到了咱们中国传统的情人节七夕了,今天笔者就带大家来领略一下用Python表白的方式。让程序员的恋人们感受一下IT人的浪漫。    一、词云制作 首先咱们可以用之...