Найти - Пользователи
Полная версия: Mysql многопоточность.
Начало » Базы данных » Mysql многопоточность.
1
plusplus
Решил, чтобы лишних проблем не было при работе с потоками всю работу с данными переложить на MySQL. В итоге, во много потоков шлю запросы SELECT и INSERT, буквально подряд, сервер выдает MySQL has gone away. Так и должно быть или я где-то накосячил? Подскажите, как решить проблему.
Lexander
Проверьте, что все запросы шлются в одном и том же соединении.
plusplus
Lexander
Проверьте, что все запросы шлются в одном и том же соединении.
Да вроде так и делаю:
class Parser(threading.Thread):
def __init__(self,config):
threading.Thread.__init__(self)
self.config = config

def run(self):
while True:
try: item = queue.get_nowait()
except: break

try: self.posting(item)
except: traceback.print_exc()
time.sleep(0.5)

queue.task_done()
def append_to_base(self,links):
#with mutex:
for link in links:
#print link
link = link.replace("&","&")
if not "http"==link[:4]: continue
o = urlparse(link)
host = o.netloc
query = "SELECT * FROM main WHERE LOCATE('{0}',link);".format(esc_str(host))
self.db.query(query)
if not self.db.store_result().num_rows():
print link,"has been added."
query = "INSERT INTO main (link,status) VALUES('{0}','{1}')".format(esc_str(link),0)
self.db.query(query)
def posting(self,row):
t_id,link,status = row[0]
print link,"start."
url = link
post = Post()
the_page = post.get(url)

for regex in self.regulars:
if not the_page: continue
links = re.findall(regex,the_page)
self.append_to_base(links)
#with mutex:
query = "UPDATE main set status='1' where id='{0}';".format(t_id)
self.db.query(query)
def main():
config = ConfigParser.RawConfigParser()
config.read('settings.cfg')
threads = int(config.get("Basic","threads"))
regulars = [x.strip() for x in open(config.get("Basic","regulars"))]
args = dict(config.items('MySQL'))
db = _mysql.connect(host=args['host'], user=args['user'], passwd=args['passwd'], db=args['db'])
while True:
query_string = "SELECT * FROM main WHERE status='0' LIMIT 0,1000;"
db.query(query_string)
res = db.store_result()
if res.num_rows()<1:break
for i in xrange(res.num_rows()):
queue.put(res.fetch_row()) # заносим данные в очередь
#break
for i in xrange(threads):
t = Parser(config) # создаем нить
t.db = db
t.regulars = regulars
t.start() # стартуем
time.sleep(0.1)
queue.join()
print "Next round"
print "Done"
if __name__ == '__main__':
main()
plusplus
Видимо как раз наоборот надо, чтобы все запросы слались в разных соединениях. Перенес _mysql.connect в конструктор - заработало.
Lexander
Так у вас все запросы к одной и той же таблице!
Похоже, Мускул просто затыкается от потока запросов в одном соединении.
Вы временно решили проблему, переложив ограничение с одного уровня на другой - повыше.
Точно также есть ограниение на макс. количество соединений и в один прекрасный момент некоторые соединения просто будут отвергаться сервером.

Кроме того, установка соединения - это все таки достаточно дорогая операция для сервера.

Я бы все копал в сторону настроек сервера БД (зависит от желаза) или все же изменил алгоритм.
Зачем здесь потоки, если все операции идут с одной таблицей?
Они ведь все равно упираются в производительность сервера БД.
plusplus
Потоки нужны для быстрого парсинга, не для работы с таблицей.

То есть оптимальным решением будет поставить блокировки при работе с таблицей? По-моему я так даже пробовал, но точно не помню. Сейчас проблема немножко другая - сервер ложится при 70к записях, как можно это предотвратить не подскажете?
Lexander
plusplus
Потоки нужны для быстрого парсинга, не для работы с таблицей.
Если результат парсинга сохраняется в одной и той же таблице, то я вам гарантирую - это и есть узкое место.
При вставке или обновлении записи мускул блокирует таблицу на запись. Т.е. одновременно у вас работает только 1 поток.
Иногда и на чтение - зависит от настроек.

plusplus
Сейчас проблема немножко другая - сервер ложится при 70к записях, как можно это предотвратить не подскажете?
Это от многих вещей зависит: начиная от мощности железа и заканчивая настройками Мускула.

Перво-наперво посмотрите статистику работы мускула. В некоторых инструментах для Мускула (PHPMyAdmin, например) есть средства для просмотра статистики. Он же дает рекомендации, что нужно сделать, если то или иное значение статистики плохое.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB