0%

原文链接:redis数据库

介绍

Redis 是一种开源(BSD 许可)内存数据结构存储,用作数据库、缓存和消息代理。 它支持数据结构,例如字符串、散列、列表、集合、带范围查询的排序集合、位图、hyperloglogs 和带半径查询的地理空间索引。

优点

Redis 的一些主要特性是:
• 内存存储:Redis 将所有数据存储在内存中,而不是磁盘上。 这使得它非常快,因为不涉及磁盘 I/O。
• 磁盘持久化:Redis 可以将数据持久化到磁盘,以在崩溃或重启时重建内存中的数据。 这使其快速耐用。
• 复制:Redis 允许主从复制以扩展读取并确保可靠性。
• LRU 逐出:Redis 支持在达到最大内存时自动逐出键。 这是以 LRU(最近最少使用)方式完成的。
• 事务:Redis 支持事务将一组命令作为一个独立的操作来执行。
• 发布/订阅:Redis 通常用作消息代理,并通过其发布/订阅功能支持简单形式的消息传递。
• 具有多种数据类型的键:Redis 键可以保存字符串、列表、集合、排序集合、散列和位图。 这允许您将 Redis 用作数据库和缓存。
• 快速性能:Redis 是用C 语言编写的,速度极快,通常以超过100k 次操作/秒的速度运行。

应用场景

Redis 的一些常见用途是:
• 缓存——Redis 是一种理想的缓存存储,具有内存中性能和磁盘持久性。
• 会话存储——Redis 是存储用户会话数据的绝佳选择。
• 消息代理——Redis Pub/Sub 功能适用于简单的消息队列和应用程序通信。
• 分析——Redis 位图和hyperloglogs 提供了一种快速进行分析和计数的方法。

安装

  1. 依赖库安装

    1
    2
    3
    sudo apt-get update
    sudo apt-get install tcl
    sudo apt-get install libssl-dev
  2. 官网找到指定版本文件下载安装到指定的目录
    http://download.redis.io/releases/
    http://download.redis.io/releases/redis-7.0.0.tar.gz

  3. apt安装

curl -fsSL https://packages.redis.io/gpg | sudo gpg –dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo “deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main” | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt-get update
sudo apt-get install redis
redis-cli -h 127.0.0.1 -p 6379 shutdown

配置

  1. 权限修改
    给redis所在目录指定权限,apt下载的找到对应的目录chmod,否则会无法关闭

4.配置redis
redis目录/redis.conf 配置信息,如logfile等

运行

  1. 启动
    执行 redis目录/src/redis-server 启动
    redis-cli 为客户端通信命令
    redis-cli shutdown 关闭redis
    sudo /etc/init.d/redis-server stop 强制关闭

  2. redis基础命令https://redis.com.cn/commands.html
    redis-cli 回车与redis-server通信
    ping 回复pong 表示redis正常运行
    set key value
    get key

开发库hredis安装

hiredis 是一个用于与 Redis 服务器交互的 C 库。 它只是一个客户端库,它与 Redis 服务器通信但本身不存储任何数据。

  • hiredis 是一个与 redis 服务器接口的 C 库
  • hiredis 无法在不连接到 redis 服务器的情况下工作
  • 许多 redis 客户端库/包装器(如 redis-py)在后台使用 hiredis 与 redis 通信。
  • 安装hreids如下,会自动在/usr/local/lib/ /usr/local/include/hiredis中配置hiredis的依赖库
    1
    2
    3
    4
    5
    6
    7
    mkdir /app/
    cd /app/
    git clone https://github.com/redis/hiredis.git
    cd hiredis
    make
    make install

原文链接:python创建自己的package

python创建自己的package

package介绍

Python 包是提供一些附加功能的 Python 模块的目录。
包允许您将代码组织到单独的文件和文件夹中,并在需要的地方导入它们,使您的代码保持简洁

模块结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
\-packagedemo
\-packagename
-1.py
-2.py
\-dir
-__init.py
-3.py
-...
-...
-__init__.py
-__init__.py
-LICIENSE
-README.MD
-setup.py

说明

  1. package项目和setup/LICIENSE/README.MD同级
  2. packagename项目下的文件可以是任意的,但是每一个包含源码的目录下需要有__init__.py
  3. init.py可以写入该文件夹下的同级源码文件名称 all=[‘1’,’2’]
  4. 项目内import要从packagename开始

setup编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from setuptools import Extension, dist, find_packages, setup
import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
with open("README.MD", "r") as fh:
long_description = fh.read()

setup(
name='packagename',
version="X.X.X",
description='packagename',
long_description=long_description,
long_description_content_type="text/markdown",
keywords='data analysis',
url='https://github.com/XX/packagename',
author='author',
author_email='XXXX.com@gmail.com',
# packages=find_packages(),

classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],

setup_requires=['pytest-runner'],
tests_require=['pytest'],

python_requires = '>=3.6',
install_requires=[
'pandas>=2.0.0',
'scikit-learn>=1.0.0',
'numpy>=1.24.0',
'matplotlib>=3.7.0'
],

# entry_points={
# 'console_scripts': [
# 'foo = foo.main:main'
# ]
# },
# scripts=['bin/foo.sh', 'bar.py'],


)

项目打包

  1. 检查setup是否正确
    1
    python setup.py check
  2. 创建gz的安装包
    1
    python setup.py sdist 
    会在setup.py同级下生成dist文件夹,里面包括了packagename-X.X.X.tar.gz
    可用通过pip安装
    3.创建wheel安装包 需要安装wheel包
    1
    python setup.py sdist bdist_wheel
    dist下生成packagename-X.X.X.py3-none-any.whl

项目发布

使用twine上传

1
python -m twine upload --repository pypi dist/*

输入pypi的账户和密码即可,由于网络原因会存在无法上传或出错,多重复几次即可

项目测试

使用pypi安装项目
可以发布到testpypi,进行测试,testpypi会更快

1
2
pip install -i https://pypi.org/simple packagename==X.X.X
pip install -i https://test.pypi.org/simple packagename==X.X.X

原文链接:django+uwsgi网站搭建

安装环境

1.1 创建venv环境

1
2
3
4
5
apt install python3.8-venv
python3 -m venv v
source ./v/bin/activate
pip3 install --upgrade pip
python3 -m pip install --upgrade setuptools

1.2 mysql服务安装

python提供两种mysql扩展,pymysql和mysqlclient,分别对应高开发和高性能
mysqlclient:mysqlclient需要编译安装

1
2
3
4
5
apt-get install libmysqlclient  libmysqlclient-dev
pip3 install --no-cache-dir --force-reinstall -Iv mysqlclient

#pymysql:
pip install pymysql

1.3 安装包

包括uwsgi,mysql,django服务

1
2
pip install -r requirements.txt
pip install uWSGI==2.0.21 Django==4.0 mysqlclient

2 django命令

2.1 项目创建

django-admin startproject projectname

2.2 应用创建

django-admin startapp appname

2.3 数据库迁移

1
2
3
4
# 创建数据库映射
python manage.py makemigrations django
# 将修改同步数据库
python manage.py migrate

2.4 本地运行测试

python manage.py runserver 0.0.0.0:8000

2.5 uwsgi命令

1
2
3
sudo killall -9 uwsgi #关闭所有uwsgi进程
uwsgi --stop uwsgi.pid #在当前django项目文件夹下 执行关闭
uwsgi --ini uwsgi.ini #在当前django项目文件夹下 执行启动

3 settings 配置

root/projectname/settings.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- ALLOWED_HOSTS = ['*'] 设置acl
- INSTALLED_APPS 增加创建的app
- MIDDLEWARE中禁用 django.middleware.csrf.CsrfViewMiddleware
- templates修改dir为对应模板文件夹地址:'DIRS': [os.path.join(BASE_DIR, 'templates')],
- 数据库配置如下
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'aidroid',
'USER': 'root', # 数据库用户名
'PASSWORD': 'root', # 密码
'HOST': 'localhost', # 主机
'PORT': '3306', # 数据库使用的端口
}
}

- 设置静态、媒体、登录路由和根目录
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
LOGIN_URL = '/safe/login'

4 uwsgi配置与部署

在项目根目录创建uwsgi.ini,安装下配置
迁移数据库

启动nginx,启动uwsgi

1
2
sudo service nginx restart #nginx重新加载(只有当修改了nginx配置时才重启)
uwsgi --ini uwsgi.ini #在当前django项目文件夹下 执行启动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[uwsgi]

chdir = /www/wwwroot/aidroid.top/djangoweb
module = djangoweb.wsgi:application
; socket = /www/wwwroot/aidroid.top/djangoweb/uwsgi.sock
socket = 127.0.0.1:8001


daemonize = /www/wwwroot/aidroid.top/djangoweb/uwsgi.log
pidfile = /www/wwwroot/aidroid.top/djangoweb/uwsgi.pid

master = true
vacuum = true
processes = 10
max-requests = 1000
buffer-size = 65535

原文链接:cpp实现云服务器与本地主机socket通信

云服务器与本地主机socket通信

介绍

云服务器本身拥有全时间段在线的能力,可以支撑我们大部分web项目的运行需求。
但是当服务器算力不够或者是数据存在安全性问题时,我们不希望将所有任务都放置在服务器中运行,
而是会选择本地的终端提供数据或者算力服务,以达到加速或保密的需求。
实现这种需求就需要本地主机与服务器进行socket通信。

服务器

服务器端建立一个server.cpp文件,使用linux socket系统调用创建socket,设置ip和端口,
使用bind和listen绑定监听,再调用accept处理连接请求。

  • 注意服务器要开放对应的端口规则,否则无法访问
  • 同时服务器端的监听ip应该为0.0.0.0 表示允许任意ip与服务器连接,在本地运行时我们设置127.0.0.1时能连接的原因是client和server都是本地IP

客户端

客户端较为简单,指定IP为服务器公网IP,指定端口号,调用connect连接,互相发送问候消息验证。

appendix

server.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include"sys/ipc.h"
#include"sys/msg.h"
#include"iostream"
#include"unistd.h"
#include"string.h"
#include"sys/types.h"
#include"sys/shm.h"
#include"sys/socket.h"
#include"arpa/inet.h"
#include"signal.h"

int fd;
void cl(int p){
close(fd);
printf("terminated\n");
exit(-1);
}

int main(){

int socketfd;
socketfd=socket(AF_INET,SOCK_STREAM,0);

fd=socketfd;
signal(SIGINT,cl);

sockaddr_in server_addr;
server_addr.sin_family=AF_INET;
inet_pton(AF_INET,"0.0.0.0",&(server_addr.sin_addr));
server_addr.sin_port=htons(9000);
bind(socketfd,(sockaddr*)(&server_addr),sizeof(server_addr));

listen(socketfd,10);

sockaddr_in client_addr;
int conntfd;
char client_ip[16];
int client_port=0;
char msg[100];
socklen_t client_len=sizeof(client_addr);
while(1){
printf("listen...\n");
conntfd=accept(socketfd,(sockaddr*)(&client_addr),&client_len);
inet_ntop(AF_INET,&client_addr.sin_addr,client_ip,16);
client_port=ntohs(client_addr.sin_port);
printf("accept %s:%d\n",client_ip,client_port);
memcpy(msg,"hello!",sizeof("hello!"));
send(conntfd,msg,100,0);
recv(conntfd,msg,sizeof(msg),0);
printf("client:%s\n",msg);
}


return 0;
}





client.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include"sys/ipc.h"
#include"sys/msg.h"
#include"iostream"
#include"unistd.h"
#include"string.h"
#include"sys/types.h"
#include"sys/shm.h"
#include"sys/socket.h"
#include"arpa/inet.h"


int main(){


int socketfd;
socketfd=socket(AF_INET,SOCK_STREAM,0);



struct timeval tv;
tv.tv_sec=0;
tv.tv_usec=0;
setsockopt(socketfd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv));



sockaddr_in server_addr;
server_addr.sin_family=AF_INET;
inet_pton(AF_INET,"47.102.99.208",&(server_addr.sin_addr));
server_addr.sin_port=htons(9000);
int c=0;
while(connect(socketfd,(sockaddr*)(&server_addr),sizeof(server_addr))==-1)
{
sleep(1);
printf("reconnect %d\n",++c);
}
printf("connect success!\n");
char msg[100];
recv(socketfd,msg,sizeof(msg),0);
printf("server:%s\n",msg);
memcpy(msg,"hi!",sizeof("hi!"));
if( send(socketfd,msg,100,0)<0){
perror("send");
}
close(socketfd);
return 0;
}