Python运维项目中用到的redis经验及数据类型

Redis实战技巧
本文分享了作者在使用Redis过程中的心得,包括如何利用Redis集合解决实际问题、提高性能的方法,以及在高并发场景下如何合理使用Redis进行队列管理。


先感叹下,学东西一定要活学活用!   我用redis也有几年的历史了,今个才想到把集合可以当python list用。  最近做了几个项目都掺杂了redis, 遇到了一些个问题和开发中提高性能的方法,这都分享出来,共同学习。


下面先简单讲讲Redis集合的数据类型。


Sets 就是一个集合,集合的概念就是一堆不重复值的组合。利用Redis提供的Sets数据结构,可以存储一些集合性的数据,比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。  上面说的是新浪微博的应用。  



sadd,创建一个集合,并添加数据。

[root@66 ~]# redis-cli
redis 127.0.0.1:6379> 
redis 127.0.0.1:6379> 
redis 127.0.0.1:6379> sadd xiaorui aaa
(integer) 1
redis 127.0.0.1:6379> sadd xiaorui bbb
(integer) 1
redis 127.0.0.1:6379> sadd xiaorui ccc
(integer) 1
redis 127.0.0.1:6379> 
redis 127.0.0.1:6379> SMEMBERS xiaorui
1) "aaa"
2) "ccc"
3) "bbb"
redis 127.0.0.1:6379> 
redis 127.0.0.1:6379>


set集合是不能写重复的内容的

redis 127.0.0.1:6379> sadd xiaorui fuck_shencan
(integer) 1
redis 127.0.0.1:6379> sadd xiaorui fuck_shencan
(integer) 0
redis 127.0.0.1:6379>


查看集合的大小

redis 127.0.0.1:6379> SCARD xiaorui
(integer) 3
redis 127.0.0.1:6379>


删除

redis 127.0.0.1:6379> SREM xiaorui aaa
(integer) 1
redis 127.0.0.1:6379> SMEMBERS xiaorui
1) "ccc"
2) "bbb"
redis 127.0.0.1:6379>


两个集合的交集之处

redis 127.0.0.1:6379> SADD key1 a
(integer) 1
redis 127.0.0.1:6379> SADD key1 b
(integer) 1
redis 127.0.0.1:6379> SADD key1 c
(integer) 1
redis 127.0.0.1:6379> SADD key2 c
(integer) 1
redis 127.0.0.1:6379> SADD key2 d
(integer) 1
redis 127.0.0.1:6379> SADD key2 e
(integer) 1
redis 127.0.0.1:6379> SINTER key1 key2
1) "c"
redis 127.0.0.1:6379>


可以把集合当成redis list队列用,需要注意的是set集合的成员模式是不能有重复的值的。如果你的值不重复,你又蛋疼,还真的可以把set集合当成队列使用。 


redis 127.0.0.1:6379> sadd myset one
(integer) 1
redis 127.0.0.1:6379> sadd myset two
(integer) 1
redis 127.0.0.1:6379> sadd myset three
(integer) 1
redis 127.0.0.1:6379> SPOP myset
"one"
redis 127.0.0.1:6379> SMEMBERS myset
1) "three"
2) "two"
redis 127.0.0.1:6379>
原文:


前两天和朋友说,我那监控平台的内存吃的厉害,他一下子蹦出一句,redis吃内存肯定很大了。。。 nima,哥只是用他的大队列。这里说下,redis做队列的强度。一把来说100w条的队列数据,占用73M 内存左 右。200w条数据内存在154M内存左右。  

原文:http://rfyiamcool.blog.51cto.com/1030776/1435539


redis的堵塞取任务,最好少用,超过5个线程去brpop的话,会把redis的cpu使用率顶到80%左右,而且严重会影响别的进程的访问,如果确定任务不是每时每刻都有的情况下,最好在你的程序控制下他的访问频次和时间的间隔。


python处理redis的时候,最好要用pool,速度和资源明显的节省。 

>>> pool = redis.ConnectionPool(host='localhost', port=6379, db=0)

>>> r = redis.Redis(connection_pool=pool)


新版的redis是支持管道的,pipline !   有朋友不太理解,这里的管道有什么好处。 pyhton 虽然连接redis的时候用了连接池,但是这也只是连接方面做了keepalive而已,但是每次的命令推送,他还是一次命令一个交互的。 用了pipline管道堵塞后,他会把所有的命令合成一个管道符推送到redis服务端。这样的话就省事了很多。  这个特别适用于并发大的时候。


原文:http://rfyiamcool.blog.51cto.com/1030776/1435539


对于redis的pub sub通信性能的问题,可以用gevent来搞定。直接导入gevent猴子就可以了。

import gevent.monkey
gevent.monkey.patch_all()
#http://rfyiamcool.blog.51cto.com/1030776/1435539 
import os
import sys
import fcntl
import gevent
from gevent.socket import wait_read
 
from redis import Redis
 
PID = os.getpid()
 
red = Redis('localhost')
 
def echo_stdin():
    # make stdin non-blocking
    fcntl.fcntl(sys.stdin, fcntl.F_SETFL, os.O_NONBLOCK)
    red.publish('echo', "[%i] joined" % (PID,))
    while True:
        wait_read(sys.stdin.fileno())
        l = sys.stdin.readline().strip()
        s = "[%i] %s" % (PID, l)
        # save to log
        red.rpush('echo_log', s)
        # publish message
        red.publish('echo', s)
        if l == 'quit':
            break
 
def handler():
    pubsub = red.pubsub()
    # first subscribe, then print log (no race condition this way)
    pubsub.subscribe('echo')
    # print log
    for line in red.lrange('echo_log', 0, -1):
        print '.', line
    # print channel
    for msg in pubsub.listen():
        print '>', msg['data']
 
gevent.spawn(handler)
gevent.spawn(echo_stdin).join()


当然对于普通的set get sadd hset 也是可以配合redis来使用的。但是,没啥优势,因为redis只启用了一个进程针对数据的读写,咱们从程序中复用的那几个连接,最后取数据,还是需要调用那进程,你还不如让他老老实实的干活,别搞个多线程,让他白白折腾。 我这边做了压力测试,python2.7用个gevent后,批量的读写没什么突出的增长。

>>> import geventredis
>>> redis_client = geventredis.connect('127.0.0.1', 6379)
>>> redis_client.set('foo', 'bar')
'OK'
>>> for msg in redis_client.monitor():
       print msg



<think>好的,用户问的是如何用Python搭建数据平台。首先,我需要明确用户的需求。数据平台可能有很多种类型,比如数据分析平台、数据仓库、实时处理平台等。用户可能是一个有一定技术背景的人,但可能对具体步骤和工具不太熟悉,所以需要分步骤解释,并且推荐合适的工具和库。 首先,我应该考虑数据平台的基本架构。通常包括数据采集、存储、处理、分析和可视化这几个部分。然后,针对每个部分,用Python有哪些常用的库和框架。比如数据采集可以用Requests或Scrapy,存储可能涉及数据库,比如PostgreSQL或MySQL,或者大数据存储如Hadoop、HDFS,但Python可能更多用SQLAlchemy或PyMongo来连接不同的数据库。 数据处理和分析部分,Pandas和NumPy是基础,可能还需要提到Dask处理大数据。对于实时处理,可能需要用到Kafka加上PySpark。数据可视化的话,Matplotlib、Seaborn、Plotly都是常见的选择。如果涉及到机器学习,Scikit-learn、TensorFlow、PyTorch这些库也要提到。 然后,用户可能想知道具体的步骤。第一步是明确需求,确定平台的目标和规模,比如是处理实时数据还是批量处理,数据量有多大,是否需要扩展性。接下来是技术选型,根据需求选择合适的工具,比如小规模数据可能用Pandas,大规模可能需要分布式系统如Spark。 然后是数据采集和存储,需要解释如何从不同来源获取数据,比如API、数据库、日志文件,存储到合适的地方。数据处理和清洗部分,要介绍如何使用Pandas进行数据清洗,可能还需要数据转换和聚合。数据分析和建模部分,可能需要统计分析和机器学习模型。可视化方面,生成图表和仪表盘,比如用Dash或Streamlit构建交互式界面。 部署和运维也是重要的一环,可能需要使用Docker容器化,Kubernetes编排,以及监控工具如Prometheus。最后,持续优化和迭代,根据反馈调整架构。 需要提醒用户注意数据安全、性能优化和可扩展性。可能用户没有考虑到这些方面,所以需要特别指出。还要确保每个步骤都给出具体的库或工具的例子,比如用FastAPI构建API,Celery处理异步任务,Airflow做任务调度。 可能需要检查是否有遗漏的部分,比如权限管理、身份验证,或者数据平台的扩展性设计。另外,用户可能对某些工具不熟悉,所以需要简要介绍每个工具的作用,比如Dask用于并行计算,Spark用于大规模数据处理。 最后,要确保整个流程结构清晰,分步骤说明,让用户能够按照步骤一步步搭建。同时,语言要简洁,避免过于技术化,让不同层次的用户都能理解。</think>### 如何用 Python 搭建数据平台(分步指南) 数据平台的核心目标是实现数据的采集、存储、处理、分析和可视化。以下是基于 Python 的搭建流程: --- #### **1. 明确需求与架构设计** - **目标**:确定平台用途(如实时分析、批处理、机器学习等)和规模(数据量、用户量)。 - **架构示例**: ``` 数据源 → 采集层 → 存储层 → 处理层 → 分析层 → 可视化层 ``` --- #### **2. 技术选型** | 功能 | 推荐工具 | |--------------|--------------------------------------------------------------------------| | **数据采集** | Requests(API)、Scrapy(爬虫)、Kafka-Python(实时流) | | **数据存储** | PostgreSQL(关系型)、MongoDB(文档型)、MinIO(对象存储)、Parquet(文件)| | **数据处理** | Pandas(小数据)、Dask(分布式)、PySpark(大数据) | | **任务调度** | Apache Airflow(工作流)、Celery(异步任务) | | **可视化** | Dash/Streamlit(交互式仪表盘)、Superset(BI工具) | | **部署** | Docker(容器化)、Kubernetes(集群管理)、FastAPI(后端服务) | --- #### **3. 数据采集与存储** - **代码示例(API 数据采集)**: ```python import requests import pandas as pd # 从 API 获取数据 response = requests.get("https://api.example.com/data") data = response.json() # 存储到 CSV df = pd.DataFrame(data) df.to_csv("data.csv") # 存储到数据库(以 PostgreSQL 为例) from sqlalchemy import create_engine engine = create_engine("postgresql://user:password@localhost/dbname") df.to_sql("table_name", engine, if_exists="replace") ``` --- #### **4. 数据处理与清洗** - **使用 Pandas 处理数据**: ```python # 数据清洗示例 df = pd.read_csv("data.csv") df = df.dropna() # 删除缺失值 df["timestamp"] = pd.to_datetime(df["timestamp"]) # 时间格式转换 ``` - **分布式处理(Dask)**: ```python import dask.dataframe as dd ddf = dd.read_csv("large_data_*.csv") result = ddf.groupby("category").sum().compute() ``` --- #### **5. 数据分析与建模** - **统计分析**: ```python # 描述性统计 print(df.describe()) # 相关性分析 correlation = df.corr() ``` - **机器学习(Scikit-learn)**: ```python from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier X_train, X_test, y_train, y_test = train_test_split(X, y) model = RandomForestClassifier() model.fit(X_train, y_train) ``` --- #### **6. 数据可视化与交互** - **Dash 仪表盘示例**: ```python import dash import dash_core_components as dcc import dash_html_components as html app = dash.Dash() app.layout = html.Div([ dcc.Graph(figure=px.line(df, x="date", y="value")) ]) app.run_server(port=8050) ``` --- #### **7. 部署与运维** - **容器化部署(Docker)**: ```dockerfile FROM python:3.9 COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:8000"] ``` - **监控与日志**: - 使用 Prometheus + Grafana 监控性能 - 通过 Loguru 或 ELK 栈管理日志 --- #### **注意事项** 1. **数据安全**:加密敏感数据(如用 `cryptography` 库),设置访问权限(RBAC)。 2. **性能优化**:使用缓存(Redis)、异步任务(Celery + RabbitMQ)。 3. **扩展性**:采用微服务架构,分离存储与计算层。 --- #### **完整案例参考** - **工具链组合**:Airflow(调度) + PySpark(ETL) + PostgreSQL(存储) + Streamlit(前端) - **开源项目**:参考 Apache Superset 或 MLflow 的设计模式。 通过模块化设计和合理的技术选型,Python 可高效搭建灵活、可扩展的数据平台。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值