力扣sql

1.sql查找所有至少连续出现三次的数字

建表

create table `logs` (
`id` int (10),
`num` int (11)
);
insert into `logs` (`id`, `num`) values(‘1′,’1’);
insert into `logs` (`id`, `num`) values(‘2′,’2’);
insert into `logs` (`id`, `num`) values(‘3′,’3’);
insert into `logs` (`id`, `num`) values(‘4′,’1’);
insert into `logs` (`id`, `num`) values(‘5′,’1’);
insert into `logs` (`id`, `num`) values(‘6′,’1’);
insert into `logs` (`id`, `num`) values(‘7′,’3’);
insert into `logs` (`id`, `num`) values(‘8′,’3’);
insert into `logs` (`id`, `num`) values(‘9′,’4′);
insert into `logs` (`id`, `num`) values(’10’,’4′);
insert into `logs` (`id`, `num`) values(’11’,’4′);

查询

SELECT DISTINCT Num AS ConsecutiveNums
FROM (
SELECT Num,
CASE
WHEN @currnet = Num THEN @count := @count + 1
WHEN (@currnet := Num) IS NOT NULL THEN @count := 1
END AS CNT
FROM LOGS, (SELECT @currnet := NULL,@count := 0) AS t
) AS temp
WHERE temp.CNT >= 3

结果是数字:1 和 4

 

2.编写一个 SQL 查询来实现分数排名。

如果两个分数相同,则两个分数排名(Rank)相同。请注意,平分后的下一个名次应该是下一个连续的整数值。换句话说,名次之间不应该有“间隔”。

+—-+——-+
| Id | Score |
+—-+——-+
| 1 | 3.50 |
| 2 | 3.65 |
| 3 | 4.00 |
| 4 | 3.85 |
| 5 | 4.00 |
| 6 | 3.65 |
+—-+——-+
例如,根据上述给定的 Scores 表,你的查询应该返回(按分数从高到低排列):

+——-+——+
| Score | Rank |
+——-+——+
| 4.00 | 1 |
| 4.00 | 1 |
| 3.85 | 2 |
| 3.65 | 3 |
| 3.65 | 3 |
| 3.50 | 4 |
+——-+——+

实现:

SELECT s1.Score,COUNT(DISTINCT(s2.score)) Rank
FROM
Scores s1,Scores s2
WHERE
s1.score<=s2.score
GROUP BY s1.Id
ORDER BY Rank;

分析:s1.score<=s2.score筛选出包含自己和比自己大的s2.score
COUNT(DISTINCT(s2.score)) Rank 按 s1.Id分组,去重统计有几个包含自己和比自己大的s2.score,也就得到了s2.score的排序,最后按照Rank排序
3.换座位

示例:

+———+———+
| id | student |
+———+———+
| 1 | Abbot |
| 2 | Doris |
| 3 | Emerson |
| 4 | Green |
| 5 | Jeames |
+———+———+
假如数据输入的是上表,则输出结果如下:

+———+———+
| id | student |
+———+———+
| 1 | Doris |
| 2 | Abbot |
| 3 | Green |
| 4 | Emerson |
| 5 | Jeames |
+———+———+

select
case
when id!=counts and mod(id,2)!=0 then id+1
when id=counts and mod(id,2)!=0 then id
else id-1 end
as id,student
from seat,(select count(*) as counts from seat) as b order by id

Dockerfile安装nginx

1.新建并进入docker_demo文件夹

2. wget http://nginx.org/download/nginx-1.17.2.tar.gz

新建文件Dockerfile内容:

# base image
FROM centos

# MAINTAINER
MAINTAINER 1406563994@qq.com.com

# put nginx-1.17.2.tar.gz into /usr/local/src and unpack nginx
ADD nginx-1.17.2.tar.gz /usr/local/src

# running required command
RUN yum install -y gcc gcc-c++ glibc make autoconf openssl openssl-devel
RUN yum install -y libxslt-devel -y gd gd-devel  pcre pcre-devel
RUN useradd -M -s /sbin/nologin nginx

VOLUME ["/data"]

# change dir to /usr/local/src/nginx-1.17.2
WORKDIR /usr/local/src/nginx-1.17.2

# execute command to compile nginx
RUN ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-file-aio --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module  --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module && make && make install

ENV PATH /usr/local/nginx/sbin:$PATH

EXPOSE 80

ENTRYPOINT ["nginx"]

CMD ["-g"]



3.构建

docker build -t centos_nginx_v1:v1 .

4.启动

docker run -d -p 80:80 --name=centos_nginx_v1 centos_nginx_v1:v1 -g "daemon off;"

5.浏览器访问80端口

raft算法选举

1.角色

raft协议中,一个节点任一时刻处于以下三个状态之一:

    • leader
    • follower
    • candidate

所有节点启动时都是follower状态;在一段时间内如果没有收到来自leader的心跳,从follower切换到candidate,发起选举;如果收到majority的赞成票(含自己的一票)则切换到leader状态;如果发现其他节点比自己更新,则主动切换到follower。从raft的论文中可以看到,leader转换成follower的条件是收到来自更高term的消息,如果网络分割一直持续,那么stale leader就会一直存在。而在raft的一些实现或者raft-like协议中,leader如果收不到majority节点的消息,那么可以自己step down,自行转换到follower状态

总之,系统中最多只有一个leader,如果在一段时间里发现没有leader,则大家通过选举-投票选出leader。leader会不停的给follower发心跳消息,表明自己的存活状态。如果leader故障,那么follower会转换成candidate,重新选出leader。

2.选举

上面已经说过,如果follower在election timeout内没有收到来自leader的心跳,(也许此时还没有选出leader,大家都在等;也许leader挂了;也许只是leader与该follower之间网络故障),则会主动发起选举。步骤如下:

  • 增加节点本地的 current term ,切换到candidate状态
  • 投自己一票
  • 并行给其他节点发送 RequestVote RPCs
  • 等待其他节点的回复

在这个过程中,根据来自其他节点的消息,可能出现三种结果

  1. 收到majority的投票(含自己的一票),则赢得选举,成为leader
  2. 被告知别人已当选,那么自行切换到follower
  3. 一段时间内没有收到majority投票,则保持candidate状态,重新发出选举

第一种情况,赢得了选举之后,新的leader会立刻给所有节点发消息,广而告之,避免其余节点触发新的选举。在这里,先回到投票者的视角,投票者如何决定是否给一个选举请求投票呢,有以下约束:

  • 在任一任期内,单个节点最多只能投一票
  • 候选人知道的信息不能比自己的少(这一部分,后面介绍log replication和safety的时候会详细介绍)
  • first-come-first-served 先来先得

第二种情况,比如有三个节点A B C。A B同时发起选举,而A的选举消息先到达C,C给A投了一票,当B的消息到达C时,已经不能满足上面提到的第一个约束,即C不会给B投票,而A和B显然都不会给对方投票。A胜出之后,会给B,C发心跳消息,节点B发现节点A的term不低于自己的term,知道有已经有Leader了,于是转换成follower。

第三种情况,没有任何节点获得majority投票,比如下图这种情况:

总共有四个节点,Node C、Node D同时成为了candidate,进入了term 4,但Node A投了NodeD一票,NodeB投了Node C一票,这就出现了平票 split vote的情况。这个时候大家都在等啊等,直到超时后重新发起选举。如果出现平票的情况,那么就延长了系统不可用的时间(没有leader是不能处理客户端写请求的),因此raft引入了randomized election timeouts来尽量避免平票情况。同时,leader-based 共识算法中,节点的数目都是奇数个,尽量保证majority的出现。

centos8安装docker

1.下载docker-ce的repo

curl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo

2.安装依赖(这是相比CentOS 7的关键步骤

yum install https://download.docker.com/linux/Fedora/30/x86_64/stable/Packages/containerd.io-1.2.6-3.3.fc30.x86_64.rpm

3.安装docker-ce

yum install docker-ce

4.启动docker

systemctl start docker

参考地址:https://www.linuxprobe.com/centos81-install-docker.html

docker对外映射端口,推送镜像

1.如果docker服务已经创建,但需要新增对外端口,可执行如下操作:

停止:                                            docker stop mongos
将容器commit成为一个镜像:docker commit mongos yang_mongos
删除原来docker:                      docker rm mongos
增加端口映射 :     docker run -it -d –name mongos -p 27017:27017 yang_mongos

2.把镜像推到远端服务器 ,首先需要有docker账户,地址https://hub.docker.com

命名规范 docker服务器username/镜像名称 如下

docker commit config_server2 chunleiyang/config_server2
docker login
docker push chunleiyang/config_server2

登录查看,推送成功

3.其他

推送镜像到服务器报:denied: requested access to the resource is denied

原因及解决:

1.未登录  ,需docker login

2.镜像命不符合规范 ,改为docker服务器username/镜像名称

或打标签:docker tag oldRepositoryName:oldTag user/rep:18.04

 

docker搭建分片mongo集群(笔记)

参考:https://www.jianshu.com/p/7be177d669be?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

1.创建配置服务集群(mongo3.4之后的版本必须2个节点以上)
(1)创建服务
docker run --name config_server1 -d mongo --configsvr --replSet "rs_config_server"  --bind_ip_all
docker run --name config_server2 -d mongo --configsvr --replSet "rs_config_server"  --bind_ip_all
(2)查看服务IP
docker inspect config_server1 | grep IPAddress
(3)进入mongo容器
由于--configsvr的默认端口为27019。所以配置服务的地址为: docker exec -it config_server1 bash mongo --host 172.17.0.2 --port 27019
(4)初始化集群配置
cfg={
_id: "rs_config_server",
configsvr: true,
members: [
{ _id : 0, host : "172.17.0.2:27019" },
{ _id : 1, host : "172.17.0.3:27019" }
]
}

rs.initiate(cfg)
2.创建分片集群
docker run --name shard_server11 -d mongo --shardsvr --replSet "rs_shard_server1"  --bind_ip_all
docker run --name shard_server12 -d mongo --shardsvr --replSet "rs_shard_server1"  --bind_ip_all

docker run --name shard_server21 -d mongo --shardsvr --replSet "rs_shard_server2"  --bind_ip_all
docker run --name shard_server22 -d mongo --shardsvr --replSet "rs_shard_server2"  --bind_ip_all
通过docker inspect shard_server11 | grep IPAddress获取对应的docker容器实例IP 由于--shardsvr的默认端口为27018。所以地址为 docker exec -it shard_server11 bash mongo --host 172.17.0.4 --port 27018
cfg={
_id : "rs_shard_server1",
members: [
{ _id : 0, host : "172.17.0.4:27018" },
{ _id : 1, host : "172.17.0.5:27018" }
]
}
rs.initiate(cfg)
mongo --host 172.17.0.6 --port 27018
cfg={
    _id : "rs_shard_server2",
    members: [
    { _id : 0, host : "172.17.0.6:27018" },
    { _id : 1, host : "172.17.0.7:27018" }
    ]
    }
rs.initiate(cfg)
3.连接 mongos 到分片集群
由于镜像的默认入口是 mongod,所以要通过 --entrypoint "mongos" 将其改为 mongos:
docker run --name mongos -d --entrypoint "mongos" mongo --configdb rs_config_server/172.17.0.2:27019,172.17.0.3:27019 --bind_ip_all
地址为:172.17.0.8:27017
4.增加分片到集群
docker exec -it mongos bash
mongo --host 172.17.0.8 --port 27017
sh.addShard("rs_shard_server1/172.17.0.4:27018,172.17.0.5:27018")
sh.addShard("rs_shard_server2/172.17.0.6:27018,172.17.0.7:27018")
5.数据库启用分片
sh.enableSharding("test")
6.分片 Collection:对 test.order 的 _id 字段进行哈希分片:
sh.shardCollection("test.order", {"_id": "hashed" })
7.插入数据
use test
for (i = 1; i <= 1000; i=i+1){db.order.insert({'price': 1})}
8.查看数据分布
mongos> db.order.find().count()
1000

rs_shard_server1:PRIMARY> db.order.find().count()

rs_shard_server2:PRIMARY> db.order.find().count()
9.其他
以上信息输出,表示安装成功。使用mongo客户端nosqlbooster发现连接失败,查看发现mongos服务对外端口未开放,修改如下
docker stop mongos
将容器commit成为一个镜像
docker commit mongos yang_mongos
docker rm mongos
docker run -it -d --name mongos -p 27017:27017 yang_mongos

连接测试:

基于副本集模式的docker搭建mongodb集群

1.拉取镜像

docker pull mongo

2.创建容器,设置副本集名称: mongo_clus(必须)

docker run -di --name=master_mongo -p 27018:27017 mongo:latest --replSet mongo_clus

docker run -di --name=backup_mongo -p 27019:27017 mongo:latest --replSet mongo_clus

docker run -di --name=arbi_mongo -p 27020:27017 mongo:latest  --replSet mongo_clus

3.登录master_mongo,创建集群,查看集群状态。

docker exec  -it master_mongo /bin/bash

mongo --host 192.168.222.128 --port 27018

cfg={ "_id":"mongo_clus", members:[ { _id:0, host:"192.168.222.128:27018", priority:2 }, { _id:1, host:"192.168.222.128:27019", priority:1 }, { _id:2, host:"192.168.222.128:27020", arbiterOnly:true } ] }

rs.initiate(cfg)

rs.status()

4.使用nosqlbooster连接测试,插入测试数据

use studies
db.createCollection("person", { capped : true, size : 50 * 1024 * 1024, max : 100 * 1000 } )
db.person.insert({name:"杨春雷",age:30})

(2)单独连接备份库是否有数据

5.关闭开启master_mongo查看主备切换是否正常

docker stop master_mongo
docker start master_mongo

grpc执行–go_out报错

执行命令:

protoc --go_out=./   ./a.proto

报错:

ERROR: 2020/10/21 11:54:10 [profiling] error parsing flags: when -address isn't specified, you must include -stream-stats-catapult-json
--go_out: protoc-gen-go: Plugin failed with status code 1.

解决:(原因:找不到protoc-gen-go可执行文件路径)

protoc --plugin=protoc-gen-go=../../bin/protoc-gen-go.exe --go_out=plugins=grpc:./ ./helloworld/helloworld.p
roto

简单实现grpc通信

仿照别人代码实现

1.新建python项目,创建文件夹

编辑helloworld.proto文件

syntax = "proto3";

package rpc_package;

// define a service
service HelloWorldService {
    // define the interface and data type
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// define the data type of request
message HelloRequest {
    string name = 1;
}

// define the data type of response
message HelloReply {
    string message = 1;
}

执行,生成rpc_package文件夹下的两个文件

python -m grpc_tools.protoc -I=./protos --python_out=./rpc_package
 --grpc_python_out=./rpc_package ./protos/helloworld.proto
2.安装模块
python -m pip install grpcio 
python -m pip install grpcio-tools
3.编辑server.py和lient.py文件

hello_server.py

#!/usr/bin/env python
# -*-coding: utf-8 -*-

from concurrent import futures
import grpc
import logging
import time

from rpc_package.helloworld_pb2_grpc import add_HelloWorldServiceServicer_to_server, \
    HelloWorldServiceServicer
from rpc_package.helloworld_pb2 import HelloRequest, HelloReply


class Hello(HelloWorldServiceServicer):

    # 这里实现我们定义的接口
    def SayHello(self, request, context):
        return HelloReply(message='Hello, %s!' % request.name)


def serve():
    # 这里通过thread pool来并发处理server的任务
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

    # 将对应的任务处理函数添加到rpc server中
    add_HelloWorldServiceServicer_to_server(Hello(), server)

    # 这里使用的非安全接口,世界gRPC支持TLS/SSL安全连接,以及各种鉴权机制
    server.add_insecure_port('[::]:50000')
    server.start()
    try:
        while True:
            time.sleep(60 * 60 * 24)
    except KeyboardInterrupt:
        server.stop(0)


if __name__ == "__main__":
    logging.basicConfig()
    serve()

编辑hello_client.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function
import logging

import grpc
from rpc_package.helloworld_pb2 import HelloRequest, HelloReply
from rpc_package.helloworld_pb2_grpc import HelloWorldServiceStub

def run():
    # 使用with语法保证channel自动close
    with grpc.insecure_channel('localhost:50000') as channel:
        # 客户端通过stub来实现rpc通信
        stub = HelloWorldServiceStub(channel)

        # 客户端必须使用定义好的类型,这里是HelloRequest类型
        response = stub.SayHello(HelloRequest(name='eric'))
    print ("hello client received: " + response.message)

if __name__ == "__main__":
    logging.basicConfig()
    run()
4.执行

窗口1,先执行python hello_server.py

窗口2,执行 python hello_client.py

输出  hello client received: Hello, eric!   成功

mysql表range分区

按天分区
CREATE TABLE `day` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `create_time` DATETIME NOT NULL COMMENT '入库时间',
  PRIMARY KEY (`id`,`create_time`)
) ENGINE=INNODB AUTO_INCREMENT=4190 DEFAULT CHARSET=utf8 COMMENT='网点系统接口请求日志表'
/*!50500 PARTITION BY RANGE  COLUMNS(create_time)
(PARTITION p20200904 VALUES LESS THAN ('2020-09-05') ENGINE = InnoDB,
 PARTITION p20200905 VALUES LESS THAN ('2020-09-06') ENGINE = InnoDB,
 PARTITION p20200906 VALUES LESS THAN ('2020-09-07') ENGINE = InnoDB,
 PARTITION p20200907 VALUES LESS THAN ('2020-09-08') ENGINE = InnoDB,
 PARTITION pmax VALUES LESS THAN (MAXVALUE) ENGINE = InnoDB) */

继续阅读“mysql表range分区”