redis的最佳使用場景是快取,用來持久化資料儲存也是可以的,但既然有更適合於用作持久化資料儲存的資料庫,我們為什麼不用呢,做到物盡其用,發揮其最大優勢,所以redis中有的資料,也有必要在mysql中進行儲存。
思路:我們可以使用python語言來編寫乙個程式,連線redis資料庫,連線mysql資料庫,再從redis裡面讀出資料,將資料插入到mysql資料庫中,最後新建乙個shell檔案,在檔案裡面呼叫寫好的python程式即可。詳細操作步驟如下:
1. 導包
import json # json是一種輕量級的資料交換格式,後續程式中會用到json.loads()將已編碼的json字串解碼為python物件,json.dumps()是將python物件編碼成json字串
import redis
import pymysql
2. 定義主函式def
main()
:# 指定redis資料庫
rediscli = redis.strictredis(host=
'ip『, port=port, password='password', db=0)
# 指定mysql資料庫
mysqlcli = pymysql.connect(host=
"localhost"
, port=
3306
, user=
"user"
, passwd=
"password"
, db=
"task"
, charset=
"utf8"
)# 指定unique_id為唯一索引
point_unique =
'alter table tb_stop_record add unique key(`unique_id`)'
mysqlcli.cursor(
).execute(point_unique)
# 設定lrange取值的起始值和終止值,步長,頁數初始值設為0
page_start =
0 step =
2 page_end = page_start + step
page_num =
0# 統計出頁數
while
true
: data = rediscli.lrange(
'acct_stop_record'
, start=page_start, end=page_end)
# 判斷獲取到的資料是否為空
if data:
page_start = page_end +
1 page_end = page_start + step
page_num +=
1# 如果獲取到的資料為空,則跳出迴圈
else
:break
# 重新設定lrange取值的起始值和終止值,步長,資料總數初始值設為0,實際插入的資料條數初始值為0
page_start =
0 step =
2 page_end = page_start + step
total =
0 count =
0for page in
range(0
, page_num)
: data_list = rediscli.lrange(
'acct_stop_record'
, start=page_start, end=page_end)
page_start = page_end +
1 page_end = page_start + step
params =
for data in data_list:
total +=
1 item = json.loads(data)
if item.get(
'session_id'):
([item.get(
'session_id'
), item.get(
'unique_id'
), item.get(
'member_name')]
))else
:continue
try:
# 使用cursor()方法獲取游標
cursor = mysqlcli.cursor(
) sql =
"insert ignore into tb_stop_record(session_id,unique_id,member_name) " \
"values(%s,%s,%s)"
# 新增的資料量
add_num = cursor.executemany(sql, params)
count = count + add_num
mysqlcli.commit(
)# 關閉游標
cursor.close(
)except pymysql.error as e:
mysqlcli.rollback(
)print
"insert error"
, e try
:# 根據實際插入的條數和每頁的條數,計算出頁數,用math.ceil()向上取整
if count %
(step +1)
==0: page_num = count /
(step +1)
else
: page_num = math.ceil(count /
(step +1)
)# 計算最後一頁實際插入的條數
if count %
int(page_num)==0
: last_page_data_num = step +
1else
: last_page_data_num = count %
int(step +1)
print
'there are {} datas'
.format
(total)
print
'actually add {} pages,insert {} datas,per page has {} datas,the last page insert {} datas.'
.format
(int
(page_num)
, count,step +
1, last_page_data_num)
except zerodivisionerror:
print
'there are {} datas'
.format
(total)
print
'the data already exists in the database'
"""
乙個python的檔案有兩種使用的方法,第一是直接作為指令碼執行,第二是import到其他的python指令碼中被呼叫(模組重用)執行。因此if __name__ == '__main__': 的作用就是控制這兩種情況執行**的過程,在if __name__ == '__main__': 下的**只有在第一種情況下(即檔案作為指令碼直接執行)才會被執行,而import到其他指令碼中是不會被執行的。
"""if __name__ ==
"__main__"
: main(
)
在終端命令列中輸入以下命令,建立乙個shell指令碼
vim redis_mysql_script.sh
#! /bin/bash
python filename.py
sh redis_mysql_script.sh
資料轉存成功。
這一過程看似挺簡單,實際上要注意的點不少,例如從redis資料庫中取出資料時如果用blpop或者lpop的話,會將原庫中的資料刪除,而一旦資料在mysql中沒插入成功,那麼我們的資料就丟失了。如果我們使用lrange方法來讀取資料,能保證資料的安全性。sql語句中佔位符也是乙個值得注意的地方,不管是什麼型別,統一用%s作為佔位符。還有redis讀取出的資料字段的個數和mysql表中的字段個數不相等的問題,也需要注意。還有效率問題,如果用for迴圈來遍歷這個列表,那麼在列表容量大的情況下,效率會很低,因此,需要用批量來讀取,批量插入mysql資料庫。還有要解決對重複資料插入的解決。
享受知識帶來的喜悅,保持鑽研的動力,繼續努力,穩健前行。
MySQL和Redis 資料同步解決方案總結
mysql和redis 資料同步解決方案總結 現在在中集e棧工作,最近在做乙個redis箱格資訊資料同步到資料庫mysql的功能。自己想了想,也有大概方案。1 佇列同步,變跟資料2份,使用訊息佇列,乙份給redis消費,乙份給mysql消費。2 後台定時任務,定時重新整理redis中箱格資訊到資料庫...
linux轉存mysql資料庫表和資料
命令列下具體用法如下 匯出資料庫表 mysqldump u使用者名稱 p密碼 d 資料庫名 表名 指令碼名 匯入sql檔案 mysql h30.1.32.181 p3306 u root proot epolicy 匯出整個資料庫結構和資料 mysqldump h localhost uroot p...
MySQL資料匯入Redis
從mysql中將資料匯入到 redis的 mysql 多個字段拼接 1.保證mysql有表 events all time 這個就是mysql要傳遞的資料表 create table events all time id int 11 unsigned not null auto increment...