用docker搭建一个ElasticSearch集群并集成Kibana+cerebro可视化

JMeter (ElasticSearch + Kibana) | Blog

ES是一个非常流行的基于lucene的搜索和分析引擎,它提供了resetful的api非常适用于搜索、推荐、日志分析等场景,社区生态丰富,是分布式架构中非常重要的一环。下面从一个docker-compose部署一个最小化集群,并用Kibana和cerebro可视化的来一窥它的能力。

version: '3.9'
services:
  cerebro:
    image: lmenezes/cerebro
    container_name: cerebro
    ports:
      - "9000:9000"
    command:
      - -Dhosts.0.host=http://host.docker.internal:9200 
      # 因为我是mac所以用host.docker.internal代替主机名
  kibana:
    image: docker.elastic.co/kibana/kibana:7.7.0
    container_name: kibana7
    environment:
      - I18N_LOCALE=zh-CN
      - XPACK_GRAPH_ENABLED=true
      - TIMELION_ENABLED=true
      - XPACK_MONITORING_COLLECTION_ENABLED="true"
      - ELASTICSEARCH_HOSTS=http://host.docker.internal:9200
    ports:
      - "5601:5601"
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.7.0
    container_name: es7_01
    environment:
      - cluster.name=cnblogs
      - node.name=es7_01
      - bootstrap.memory_lock=true  
      # 避免使用swap,减少磁盘IO
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"  
      # 防止JVM内存回收
      - discovery.seed_hosts=172.19.0.5,172.19.0.4
      # 默认ES只搜索本机的其他节点,如果节点在其他主机上则需要在这里给出地址
      - cluster.initial_master_nodes=es7_01,es7_02   
      # 初始化时符合主节点的节点方便选举
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - es7data1:/usr/share/elasticsearch/data
    ports:
      - 9200:9200

  elasticsearch2:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.7.0
    container_name: es7_02
    environment:
      - cluster.name=cnblogs
      - node.name=es7_02
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - discovery.seed_hosts=172.19.0.5,172.19.0.4
      - cluster.initial_master_nodes=es7_01,es7_02
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - es7data2:/usr/share/elasticsearch/data
    expose:
      - 9200


volumes:
  es7data1:
    driver: local
  es7data2:
    driver: local

networks:
  default:
    external: true
    name: es7net

运行上述代码前请先创建一个名为es7net的网络: docker network create es7net
下面是配置集群几个常见配置的原则

  • bootstrap.memory_lock一般设置为true,避免使用swap
  • ES_JAVA_OPTS中Xms和Xmx设置为一致,避免jvm内存重新分配
  • cerebro起来比较快,kinaba很慢要等一下,多刷新就好了
  • 运行上面的集群请至少保证docker拥有3g以上,因为Elasticsearch by default deploys with a 1GB heap,开始只使用了2g时就会出现内存不足导致es启动失败,如果是下面几种错误信息可以尝试增加内存
master not discovered or elected yet, an election requires a node with id 
或
master not discovered yet, this node has not previously joined a bootstrapped (v7+) cluster, and this node must discover master-eligible nodes 
或
max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

启动后可以按照以下步骤逐步检查部署

1检查ES运行状态

   http://localhost:9200/_cat/health?v
显示green表示工作正常

2 登录cerebro

cb的概览非常适合作为看板,对于刚接触es的同学来说能更好的理解es集群的状态,虽然它不是官方的

3 登录kinaba,官方

官方样例数据就可以创建非常漂亮的看板/报表

可以查看非常细节的数据,并支持完整的索引操作

从125ms到11ms,记一次关键字检测过滤服务的优化 -python and Pythonnet

接上文:《高效的的关键字查找和检测(哈希表和Trie前缀树和FastCheck)在实际使用中的性能

动态语言是很慢的,它更多的是为了提高开发效率,这里的关键字过滤算法在生产环境中用原生python达到125ms 2千万字/每秒已经够用了。那么是不是可以适当的优化再快一点?

Cython,没事cython一下,带你飞

cython能把大部分python代码改为静态的c实现,甚至你可以混合c和python一起写。不过现实是大部分的pythoner如果碰到性能问题要么用go要么就是用csharp,很少去写cython。下面是用cython编译后的测试结果:

提升39%,马马虎虎,也可能跟Tool.Good源码的实现有关。此时文本的处理量已经到了3400万/每秒,用是够用了,那么能不能更快一点?

C# 是时候展现你的实力了

Tool.Good作者明显是一位纯粹的csharpner, 既然已经实现了3亿效率的代码为什么不拿来用呢。这里作为对比,我先写了一个参照的测试程序,测试环境与前文相同。代码如下

using System;
using ToolGood.Words;
namespace KeywordTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var stopwatch = System.Diagnostics.Stopwatch.StartNew();
           
            string post = System.IO.File.ReadAllText(@"D:\Projects\Opensource\ToolGood.Words\csharp\KeywordTest\sample_post");

            string[] spams = System.IO.File.ReadAllLines(@"D:\Projects\Opensource\ToolGood.Words\csharp\KeywordTest\SpamWordsCN.min.txt");

            StringSearch iwords = new StringSearch();
            iwords.SetKeywords(spams);
            stopwatch.Start();
            for (var i = 0; i < 500; i++)
            { var f = iwords.FindFirst(post); }

            stopwatch.Stop();
            var s = stopwatch.ElapsedMilliseconds;
            Console.WriteLine("测试用时(ms):" + s);
        }
    }
}
Customer Retention: 3 Easy Ways to WOW Your Customers | Car People Marketing
此时的表情

Csharp性能都这样了更别说C了,那么为什么能比cython快那么多呢。这里分两部分原因,一部分性能浪费在python和c的交互上,另一部分在cython编译时的类型推断和生成的代码优化不够,大量使用的还是pure python。咱不纠结这个,手头有这么快的csharp不用简直浪费,一脚踢走cython,黏上csharp,让它飞的更高~

接福啦- 简书

Pythonnet 闪亮登场

这可是个好东西,.net基金会项目,官方身份,神秘可靠。有了它使得python和.net交互变得简单。这里需要一提的是目前稳定版2.5.2还只支持.net 4.0,至于.net core 3和.net5需要手动安装master分支上的3.0.0dev,实现方式 也有所不同,下面是代码:

def test2():

    from clr_loader import get_coreclr
    from pythonnet import set_runtime

    rt = get_coreclr("./runtimeconfig.json")
    set_runtime(rt)
    import  clr
    clr.AddReference('ToolGood.Words')

    import clr
    from System import String
    from ToolGood.Words import StringSearch
    stringSearch=StringSearch()

    with  open('./sample_post',encoding='utf-8') as f:
        test_post = f.read()
    from System.Collections.Generic import List
    spam_words=List[String]()
    with open('././SpamWordsCN.min.txt',encoding='utf-8') as f:
        for line in [line.rstrip() for line in f]:
            spam_words.Add(String(line))

    stringSearch.SetKeywords(spam_words)
    import time
    start = time.time()
    times = 500
    while times > 0:
        f = stringSearch.FindFirst(test_post)
        times -= 1
    end = time.time()
    print('程序运行时间:%s毫秒' % ((end - start) * 1000))
{
  "runtimeOptions": {
    "tfm": "net5.0",
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "5.0.2"
    }
  }
}
4种吃了会让人开心的食物- 每日头条
此时的心情

事实上如果增加压力还能提高性能,因为交互部分压力越大性价比越高。此时的处理速度已经到了2.5亿/每秒。那么能不能再快点?烦不烦,其实也不烦,生产中怎么可能不并行呢,动不动八核十几核的,线程再来double一下,妥妥的几十亿。

为什么不直接用csharp直接做服务

当然可以,如果负载确实高换纯csharp顶上,还不够再换go,还不够把分布式也弄上。但现实是高负载的需求可能永远不会到来,为什么不把时间省下来去做更有意义的事呢?

高效的的关键字查找和检测(哈希表和Trie前缀树和FastCheck)在实际使用中的性能

Implement TRIE | Leetcode #208 - YouTube

前言:看到dudu发的博文中似乎最近的db压力来源于关键字检测,以前只关注了倒排索引,于是好奇经典的关键字查找在实际生产中性能到底是一个什么数量级?

为什么不用倒排索引

在一个文本中找到给定的关键字最快的做法是倒排索引,比如平常使用的各种搜索框如google,还有咱们在生产中分析日志时用的ES也是。它的优点是海量的文本和海量的关键字,缺点是搜索的文本加入现有索引很慢。所以它不适合:评论、即时通讯、微博、脏字过滤等对发布时间有要求的场景,而这些场景正好跟倒排索引是反过来的。

如果不用Trie树

那么如何实现一个高效的及时关键字检测算法,这里为了简单期间只关注FindFirst,而FindAll 同理。首先第一个否定的算法就是IndexOf(keyword)方法,这里假定输入文本长度n,检测的关键词数量m,关键字平均长度l,复杂度就是O(n*m*l),复杂度很高。在不知道Trie树之前很容易想到的实现是Hashtable,我想大多数程序员也是这样想的,复杂度直接降为O(n+m*l),这里要提一下好多写java和csharp的同学在实现这个算法的时候会调用substring,然后导致内存飙升,其实这个临时空间完全不需要的。下面是我用python写的一个实现,这里为简单期间回避了hashtable中碰撞的情况,一般用单向链表还有树来解决,因为知道trie了没必要去做的很完善,只是提供一个对比的数量级,而哈希表的完整实现只会比这个更慢。

def test3():

    with  open('./sample_post', encoding='utf-8') as f:
        test_post = f.read()
    spam_words={}
    with open('././SpamWordsCN.min.txt', encoding='utf-8') as f:
        words=[line.strip() for line in f]
    for w in words:
        if len(w)>0:
            spam_words[w[0]]=w
    import time

    start = time.time()
    times = 500
    while times > 0:
        for i,c in enumerate(test_post):
            if c in spam_words:
                is_found=True
                for j,sc in enumerate(spam_words):
                    if sc!=test_post[i+j]:
                        # compare failed
                        is_found=False
                        break
                # found
                if is_found:
                    #print('找到了%s'%spam_words)
                    break
        times -= 1
    end = time.time()
    print('程序运行时间:%s毫秒' % ((end - start) * 1000))

测试条件和运行环境

  • 输入文本长度:5388 from word count
  • 关键字数量:575
  • 平均长度:3 目测
  • 测试次数:500
  • 运行环境:Ryzen 5 3600 6-core 3.6GHz
多次运行后会降为650ms左右

HashTable 总结

哈希的原理就是通过对关键字的预处理,把首字母的关键字检索降为O(1),整个过滤只需要O(n)即可5k的字符过滤650ms时间对大多数小项目小网站足够了,如果是即时通信、站内消息也是勉强足够了。但是作为一个服务的话,100并发下50ms都太大了,而且这里还只是非重复的关键字,重复的关键字是脏词最常见的形式,那么可不可以更快一点。

Trie 出场

在计算机科学中,trie,又称前缀树或字典树,是一种有序树,用于保存关联数组,其中的键通常是字符串。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。— from 维基百科

关于Trie的原理可以查看Tool.Good的文章:https://www.cnblogs.com/toolgood/p/6284718.html

Trie的实现

高达2.3k星的实现:ToolGood.Words,每秒3亿的过滤效率,有多个语言版本的实现,其中以ccharp为主,python的 “咳咳”有点尴尬,从文件命名上看就不友好,而且似乎作者用来检测的字词有点过于简短,四五个关键词,不超过20个字符的文本输入完全测试不出压力。接下来试试Trie的威力,同样先从python试起,下面是测试代码:

from StringSearch import StringSearch
with  open('./sample_post',encoding='utf-8') as f:
    test_post = f.read()
with open('././SpamWordsCN.min.txt',encoding='utf-8') as f:
    spam_words = [line.rstrip() for line in f]
import time
search = StringSearch()
search.SetKeywords(spam_words)
start = time.time()
times = 500
while times > 0:

    f = search.FindFirst(test_post)
    times -= 1
end = time.time()
print('程序运行时间:%s毫秒' % ((end - start) * 1000))

Trie的实现只有之前哈希表的五分之一

测试环境下过滤效率大概是 2千万/每秒 ,看来csharp 3亿确实是可能的。 它之所以快是因为哈西表只解决了输入字符中完全不需要匹配的n,而Trie把关键字的复杂度也降低为O(max(l))。白话一点就是哈西表把indexof中遍历m遍降低为一遍,而Trie把哈希表中关键词的检测也降低为max(l),这里的l指最长的关键字长度,也可以理解为关键字的每一个字匹配都像哈希中的实现一样只需要一次匹配。O(n+max(l))的复杂度已经很低,效率极高。对于要求不高的项目直接可以耦合进现在的处理中。那么可不可以更快一点?

Fastcheck 和 TTMP

这里还有两个号称更快的算法FastCheck和TTMP,咳咳,只搜索到了博客园的帖子,不信你google。因为是改进算法,其中fastcheck在tool.goods中有实现,期待将来能再做一个评测比较。他们比Trie快在,适当的增加了空间换了可观的时间,比如fastcheck利用了类似bitmap的原理考虑了字符出现的位置,所以它在短关键字和过滤替换场景上的表现会很好。

还是前面的问题可以不可以更快一点

接下篇《从125ms到17ms,一次关键字检测过滤服务的优化》

FastAPI 中的Async (并发和async/await)

引用文地址:https://fastapi.tiangolo.com/async/

前言:fastapi是一个广泛使用的高效的restful api框架,他的作者在这篇讲解框架中使用async的说明详细举例解释了异步编程、并发和并行的区别,堪称经典,于是手痒总结如下(不敢说翻译)

async使用指导:

  • 如果这个请求比较慢,比如连接数据库读取数据、文件IO、rpc调用等一般加上async,我想普通项目里大部分请求都会多多少少跟数据库打交道,所以加的往往比较多;
  • 比较快,稳定的使用def即可,也可以把没有上面情况调用的都按照这类处理;
  • 分不清加不加就不加,放心这不是什么大的问题,我在测试中发现不加效率高一丢丢,毕竟async是要开销的,特别适合首页这种重缓存的场景;

异步编程:

Asynchronous Code是给语言层面提供一种方式描述程序在某一点等待慢操作比如慢文件读写或者需要其它资源协作,从而让计算机可以在等待中去执行其它工作。文中作者详细列举了相对于cpu和内存操作来说慢的多的慢操作如:

  • 网络通信
  • 文件读写
  • 远程api调用如rpc调用
  • 数据库操作和查询

异步是相对同步编程来说的,在执行顺序上并没有改变。实际效果就是同一台机器如果有比较多的慢操作使用异步编程可以提高吞吐率。这里再吐槽一下,大部分语言比如python、csharp、go等的async都是协程实现的,只有java是线程实现的。代价:进程>线程>协程,java不是不能用协程来实现完全是因为历史包袱,线程相对也不会丢失太多的性能。

并发和汉堡的故事

异步的描述通常称之为并发,它跟并行不是一回事,虽然他们经常都是描述在同一时间内处理不同的事情。在细节上两者大不相同,可以下面就是用汉堡的故事来理解:
你带着心爱的小妹挤进忙碌的快餐店,排队等着付钱买汉堡。
轮到你的时候,你付钱买了两个很赞的大汉堡。
付钱
收银员告诉厨房新的订单,哪怕厨房还在准备前面的汉堡
收银员告诉你取餐号码
然后你和小妹找张桌子谈谈人生谈谈理想,因为汉堡太赞需要时间慢慢做
你趁这个时间对小妹一阵猛夸,如何如何的魅力,如何如何的动人
轮到你了后去柜台取走汉堡
然后就可以和小妹一起慢慢品尝

设想一下,如果是计算机中这个故事会怎么样
排队的时候你可能需要被迫傻等,而不是做点有意义的事比如调情,因为收银员得一个个收钱
当轮到你的时候你才会忙着看菜单,点单,付钱,确认找回来的钱,就算这样你还是没有拿到汉堡,只能去找张桌子等待
直到这个时候你才可以做些有意义的事
因为你有取餐号,所以直到显示屏上通知你可以取餐都不用担心你的汉堡被偷了
最后你去柜台取餐,道谢后算是完成任务并开始任务品尝美味的汉堡。

并行汉堡

现在设想下如果不是并发,而是并行,那么你跟你的小妹来到汉堡店就不是排一个队伍了,而是并行比如8个队伍,没有收银员只有厨师。
你前面每个人都在等他们的汉堡,拿到汉堡后才能离开柜台,厨师只有交出汉堡后才会收下一位的订单。
终于等到你了,付钱,然后等待厨师去厨房做汉堡
没有取餐号,因为没人在你前面,这时你和你的小妹只能干一件事就是确保自己在第一个不让别人抢走汉堡
等待很久以后才能拿走,这里几乎没有时间给你调情,真是个悲伤的故事。
在这个并行场景中你和你的小妹是两个处理器都等待了很久。
快餐店需要8个处理器,而并发下只需要2个。
当然,这个体验肯定不好。

汉堡总结

这个场景中有非常多的等待,所以它更适合并发系统。这也是web程序遇到的问题。太多太多的用户,但是你的服务器要等待不那么快的连接,然后还要等待回应。虽然这里的等待是以毫秒记,但是加起来就很恐怖了。所以这就是为什么Web APIs都用异步。
对于大多数现有的python框架都是在异步特性出现前设计的,所以他们大多以并行的方式实现异步,性能不强。

是不是并发比并行更好?

不,使用场景不同,并发适合web程序,但不是所有。比如科学计算,图形/音频处理,机器学习,深度学习等都适合并行计算。并行计算主要解决cpu瓶颈。

阿里云vs华为云 的容器镜像服务swr使用体验

容器镜像服务是CI构建中很重要的一换,毕竟dockerhub没有私有镜像服务,它除了给你的docker镜像加速外还可以存放你的构建,最最重要的都是免费的,目前阿里华为都有类似的服务。我一直以来使用的都是阿里云容器镜像服务,速度刚刚的,今天在整镜像的时候发现死活登录不上去,检查了一遍确认都没错,一脸懵逼,就阿里一直以来的niaoxing万一是他的问题呢于是想该用华为并对使用体验做个对比。下面是阿里登录容器镜像的截图:

这里是个人凭证页,可能企业版有所不同
  • 吐槽1:固定密码也就是我一直用的,很好很方便,虽然有点小担心,但是确实门槛低,我就不喷了。
  • 吐槽2:看到我红色涂的那个了么,没错我的账号,因为特殊原因第一个原生的账号被别人用了,经历了一顿复杂的操作后我才拿到的第二个账号,这里吐槽下阿里的账号流程乱的不行,肯定没有很好的产品梳理,最后只能人工介入,是不是很阿里的smell,有经验的在用阿里产品的多多少少应该有类似的情况喷到。
  • 吐槽3:2的问题就算了,新的账号居然给我弄一堆***,阿里的同学们请问这是什么逻辑,有重复的或者任何原因用任何字符都行,来一堆***,让人总是认为背后真实的数字是什么,结果它真实的id就是星星。。。。
  • 吐槽4:星星带来的结果就是命令行里头你会提示错误,机智如我,你可以用ID来代替,ID是一串数字,可以在右上角找到

果断开始注册华为,这里赞一下登录时候的提示,当输入手机号后它会提示你选择,如果你曾经在华为不同的业务上注册的账号里选一个。另外找回账号时它不要求你全答对,这就很严谨又很人性化,最后能把账号顺利注销开始新生活。废话不多说,进入华为swr后傻眼了

原文链接:https://support.huaweicloud.com/usermanual-swr/swr_01_1000.html

这里最重要的是第三步,得到第三步就可以拼凑出4中的登录命令。

  1. 图中3里头就是用你的ak+sk hash出了登录密码,这里要赞一下的是这种方式不会丢失你的私钥,安全比阿里好多了,个人设置的固定密钥一般都比较简单。实在偷懒把生成的后的密钥记录下来即可。
  2. 最后生成命令这里更取巧,直接用了ak,ak本身就是密钥id,也就是说只要你这个密钥还用就成立,同样的你的这个ak销毁了,登录也就失效了。
  3. 这里的区域项目名可以在华为提供的可用区域里选择。我挺好奇的是阿里只给了一个杭州节点,华为给了north和east两个,难道阿里不是份额最大的厂么。

最后吐槽一下,发现使用阿里的各种镜像服务越来越不稳定,应该不是马爸爸缺钱了,估计是被人玩坏了,比如容器镜像,最近有人利用它不限制容量的漏洞来做网盘。。。华为就不行,它有2g上限,谁的镜像能上2g啊。名族之光,技术中流不是吹的。。。

理工男对衣架的选择/衣柜收纳之衣架篇

创作立场声明:拍不好,借淘宝图一用,希望给同样在思考收纳工具的值一点参考。

衣柜困局

衣柜困局

天气冷了,又到了翻衣服的时候了

首先我是个懒人,衣服叠的乱七八糟,虽然努力过把衣物分门别类,但是怪就怪总有几天是忽冷忽热的天气。作为一个理工男抓重点是咱的习惯,衣服么格子衫牛仔裤就行了,然后就这么蹉跎讲究了十几年。这几天又鼓起勇气打算用算法来科学的规划下。

首先理顺的原则非常重要,凡是都要从我懒的根本基础出发,所以太过细致繁琐的收纳一律不考虑,所有改变都要服从很顺手很方便的原则。在经历了数个小时的苦思冥想后决定之前之所以总是失败是抓错了重点,不能以整洁作为收纳的目标而忽视了天气才是决定衣物分类的最最大的影响因素。

从天气出发那么考虑的周期必须是一年中的变化,看了很多收纳文章都是按照四级来区分,天哪,我这理工男要把衣物分成四类,拜托别开玩笑了。其实回忆一下几十个春秋冬夏,不难发现真正衣物有大的区分的时候只有冬天最冷和夏天之间,也就是说夏天的时候咱不可能穿棉袄,反之依然,好吧,这是废话,但是收纳咱就可以按照这个原则来了。

当季区,缓冲区,储藏区

虽然我分为了三个区,但是实际上使用中只会分两个地方,衣柜和储藏间,下面就说说我是怎么分的。

理工男对衣架的选择/衣柜收纳之衣架篇

储藏区

:我家的储藏间离房间隔着一个客厅还是挺远的,这个每个人都不一样,但是我对储藏的定义是它可以远一点,就好象是电脑上的硬盘,你可以慢一点,但是必须得够大,咱实际上的储藏间不可能大但是能装很多是一样的道理。储藏间的原则就是当季绝对不会用的衣物才存放在这里,原则上一个月甚至两个月才会进行一次储藏间的调整,哎呀越说越像硬盘了。这里遵循之前说的最远距离原则,比如夏天,储藏间里应该是羽绒服、帽子、围巾、这些东西。这里要注意的是,但凡有可能冬夏都用到的东西(嘿嘿,我不多,可能有的人多,咱不细说),只要是可能当季用到的都不放。最后在储藏间的收纳上,建议按照队列原则,即是先进后出,换句话说就是你可以从左往右移动收纳,这样先放进去的东西最后下个周期才会用到。这个时候可能有人会觉得冬夏一年就一次,春秋是通用的有两次,队列会出现两次,其实不然,看完缓冲区您再品,细品。

理工男对衣架的选择/衣柜收纳之衣架篇

下面是购买地址:

https://item.taobao.com/item.htm?id=6332490120

当季区、缓冲区:

这个基本就是卧室里的衣柜了,如果你跟我一样有一个上图中带滚轮的室内衣架那么恭喜你,这不仅方便,还是懒人必备,当季区完全可以由它担当,其他的衣物放衣柜里作为过度区。这里安利下上面的带滚轮衣架,太好用了,不仅可以随手拉来拉去快速找衣服,下面还可以放一些内衣和袜子,比起衣柜不要太方便,高度可调节到手最舒服的位置,嗯,没错,懒人抬手也是很累的好吧。

之所以这么分配几个区域就是从衣物的使用频率来区分的,当季区就像是cpu内的缓存可以最快的速度满足当前的需求,假如温度变化大了,那么才值得多花两分钟去缓冲区就像是内存,比如夏天的时候短袖就是当季区里的,长袖的衬衫就是缓冲区里的,对了我冬季也会把衬衫放在缓冲区的,秋天衬衫是在当季区。怎么区分三个区域的衣物就想想使用频率就可以知道了。下面说说在这两个区域收纳中我使用到的神器

衣架的选择

便宜就是王道

便宜就是王道

这个必须重头戏,衣物的收纳最最用到的就是衣架了,那么怎么选衣架呢,比如上图就是我选的,没错平平无奇的衣架。选它的理由无他,便宜量足,够用,所以买一把放着解决主要矛盾:挂衣服,哈哈哈哈啊理工男对衣架的选择/衣柜收纳之衣架篇

理工男对衣架的选择/衣柜收纳之衣架篇

买上面普通衣架的时候在这家小店发现了这么个新奇的东西,哎唷我去,踏破贴无米处呀。没错,懒人么除了囊肿羞涩买的普通衣架外主力肯定得靠懒人衣架了咯,上面衣架完美解决我的各种使用场景,能挂所有衣物理工男对衣架的选择/衣柜收纳之衣架篇 。

外观展示

领口插入衣架

领口插入衣架

懒人衣架的标志就是可以从领口插进去,也是我挑选的第一标准,这里还有几款:

1号,最常见的

1号,最常见的

2号,也很常见

2号,也很常见

3号,少见

3号,少见

4号,没见过

4号,没见过

衣领插入,最重要的特点

红色标记的距离就是能插进的领口的大小,这里1号适用性最差,2号也好不到哪去,12基本有大半衣服是插不了的,这个特性聊胜于无,3号基本能适应大部分场景,但是跟我选的4号来还是差的远。最震惊的是,哪怕冬天那小口的高领毛衣它也可以轻松的进去而不会撑开哪怕一点点,就那么一下尝试就把握圈粉了。

叠挂,神奇的功能

叠挂,神奇的功能

叠挂,节省空间,神奇的分类

之前用过类似的衣架,说实话空间确实有省下来,但是并没有那么明显的作用,反倒是对于分类有奇效,哈哈没错,分类。比如哈对于懒人来说格子衫我会挂几件差不多的在上面,然后把刚洗过的挂最下面,每次只拿最上面的,对于懒人来说有时候反复穿同一件就是因为分不清哪一个是最近洗的。当然还有其他作用,比如把差不多的衣服,差不多的裤子挂一起。这个功能还常用在我会把搭配好的一整套用三个衣架挂一起,上衣+裤子+围巾,出门一手拎出来即可。

理工男对衣架的选择/衣柜收纳之衣架篇

啥都可以挂,一个衣架解决了所有衣柜里的问题

经过我的开发,发现衣柜里头不管是衣服还是裤子,甚至围巾,皮带等等都可以用这一款衣架解决。然后我就发现假如我都买这一款衣架那么一致性带来的美感会对整个衣柜的整洁度大大加分。。。。

总结

这次的衣物收纳整理以发现了一款无人问津的小衣架结束了,很久没有动力写东西了,也许这款衣架的厂家都不知道我的这些用途吧,没办法,很多用途不是懒人你是想不到的。比如我那么执着于 从领口插进去,理工男格子衫多,总是拧纽扣我会疯的,又比如用一种衣架解决所有衣物的问题,这就像是代码重构,这里头还有点小欣喜。

这家小店铺还真的不好找。

衣架店铺名是:圣乔日用品店铺

地址是:renren3d.taobao.com

衣架1:https://item.taobao.com/item.htm?id=620851237203

衣架2:https://item.taobao.com/item.htm?id=630433034430

文章转发自:https://post.smzdm.com/p/560972/

Windows10下载所有iCloud中的照片

开始只是想集中备份所有apple设备上的照片,后来发现windows上各种方式都比较麻烦。事实证明只有icloud才是唯一一种可以持续保持手机备份更新的途径。因为云上贵州的原因,现在下载速度基本不是问题了。

我有四万七千张照片,别问我为啥有那么多照片,手机更新了,但是每次都是恢复以前的一切,但是照片庞大到传统的各种导出很无力,特别是使用了icloud也是。这里icloud一定要用微软商店中的版本,老版本就是有个安装包的那个可以点击下载所有文件,问题是不会自动下载最新的,然后下载还容易中断。最新版本会再本地出现一个icloud挂载文件夹,也是windows10最新支持的,出于备份的目的我需要有的不仅仅是镜像而是真正的下载我的拷贝。可以右击资源管理器中的icloud标识选择“Always keep on this device”,他就会自动下载所有文件。

还好我开始准备这件事,已经发现了数个文件和照片不可恢复!!!


2020年12月18日更新:这个选项的变更只是增加了本地的照片,长久不用后还是会缩小占用的空间,也就是说很多还是会白下载。最终的解决的办法是写了个脚本把icloud下的文件全部拷贝到另一个不受监控的目录,这里我使用了win32api,拷贝这个东西吃过两次亏,一次是默认的拷贝居然是链接我养成了查看实际占用磁盘大小的习惯;第二次拷贝丢失了exif,对于照片来说这个exif等附加信息还是很重要的,而最佳的保存办法就是调用系统自己的copy就是win32api了。

import threading
import os, time, threading
from tqdm import tqdm
from pathlib import Path
from multiprocessing import Pool, cpu_count
from tqdm.contrib.concurrent import process_map
import win32file

total_file_size = 0
lock = threading.Lock()
base_dir = Path('xxxx')
des_dir = Path('xxxx')
file_names = os.listdir(str(base_dir))
pbar = tqdm(total=len(file_names))


def try_open(file_name):
    # print('opening at %s:\t\n' % str(time.strftime('%H:%M:%S', time.localtime())) + str(file_path))
    start_time = time.time()
    global pbar
    source_path = os.path.join(str(base_dir), file_name)
    des_path = os.path.join(str(des_dir), file_name)
    if not os.path.exists(des_path):
        # 拷文件
        # 文件已存在时,1为不覆盖,0为覆盖
        win32file.CopyFile(source_path, des_path, 1)
    pbar.update(1)


if __name__ == '__main__':
    start_time = time.time()
    r = process_map(try_open, file_names, max_workers=5)
    # with Pool(cpu_count()-2) as pool:
    #     pool.map(try_open, files)

    print("--- %s seconds at %s---" % (time.time() - start_time, time.strftime('%H:%M:%S', time.localtime())))
    # s1=os.stat(os.path.join(str(basepath),'12715.mp4'))
    # print(s1)
    # s2=os.stat(os.path.join(str(basepath),'438.mp4'))
    # print(s2)

Photoprism ,Seafile,Nextcloud,Joplin,文件相册笔记管理

本来应该分开单独写的,太久没写东西懒惰了干脆一次写完吧。

有了nas后一直在试着挖掘它的潜力,这里不得不提zerotier这个东西,完美的解决穿透和跨网的加密问题,实在是家庭nas必备。走的是udp,除了第一次连接略有延迟外速度都不错也很稳定,现在属于self-host基石中最重要的一个了。

nas玩了好多年,现在稳定使用的事赛扬的cpu和六块大硬盘。系统使用的是windows server 2019,为啥没用黑群辉,为啥没用linux。作为母系统来说win绝对是最好的,个人nas经常要解决的就是长期运行、不可间断的,比如百度网盘,长时间跑脚本的数据,这些都要求系统跟pc有很大的兼容,所以应用上win胜出。win server还提供了block级别的重复数据,所以省心的给你节省空间。这块其实专门写个专题都有必要。

好了回到主题的服务上,当然肯定都是泡在linux,宿主在windows下毫无违和感,运行的很棒。首先最重要的服务莫过于文件管理,之所以使用Seafile那是因为他的稳定和高效,请记住,php的东西都很吃资源,所以尽管nextcloud生态很好我也放弃了,如果我是大的cpu可能会考虑吧。稳定第一,nas本来就是比较耗费时间的事情,所以所有服务我都希望一次配置终生享受,或者很简单的维护,seafile配置好后同步非常稳定,很好的默默无闻的在后台工作。效率排到第二是因为cpu是赛扬,属于小功率的u,如果本来十几天的事情能通过效率在一天解决那为什么要花十几天呢。这里不得不提,所有跟php有关的服务都会效率低下,所以如果配置php相关的要留心。这里要说下只要go的服务,目前为止效率都很高!!!比如后面说的photoprism和msysgit。seafile不是go的,内核是c写的,效率就更别说了。

Seafile提供webdav服务,可以很高效的提供给joplin支持,joplin效率不高,但是它的重点在笔记体验和检索上。

最后Photoprism,最惊艳了,说说相比其他相册和文件服务没有的优点吧:

  • 最爱:go写的,无处都能感受到异步的存在,就是事情在做,还能给你的操作反馈,不会让你觉得它崩溃了,joplin在导入我的evernote笔记时就崩溃了。
  • 不更改现有的文件结构,也不用导入,直接挂在现有的图片库即可。扫描后会在目录中放入一些缩略等数据。对于有洁癖的人来说,还提供导入文件夹的模式,就是会自动将导入文件夹的图片提取出来,也不会动未识别的文件,这一块目前只有看套他这么做了的。
  • AI标签,很多相册都陆续支持这个功能了,但是photoprism做的最好,它能在很弱的设备商正常工作,效率还不低。应该是在识别的时候自动调节了识别参数,这个就很注重细节了,同样体验就非常好。
  • 在上面的这些原因下,在索引和扫描时你就能实时看到扫描的成果,然后你就很有耐心等下去。充分利用了多核的优势,go的速度真的是非常快,让照片的浏览急速无比。

怀旧服1.13 术士单刷厄运东月牙钥匙

开始都放弃了,但是每次去拿fm药都很麻烦,于是一查真有个up主做到了。

这里要说一的是如果你是牺牲毁怎么样都过了,如果跟我一样懒得洗天赋那么就要注意了。我是暗毁,跟up主一样,前面up说的很仔细也都很顺利,最后boss却死去活来几次都没过,我才发现,up主抓的那个荒野萨特tmd居然是56的jy,我找遍了一个fb都是55的,哎,这就是命。最后测试猎人萨特发现一次就过了,比up主轻松多了。抓了lr就无所谓技能了,怎么打都能过,最后我的萨特还剩三千六血。。。。[呲牙],希望对后面刷小鬼的有帮助,食谱有望了

塑料模具(注塑模具)海关编码为:8480719090

更新目前8480710090已过期,改为8480719090可用

塑料模具(注塑模具)海关编码为:8480710090,冲压模具(钣金模具)海关编码为:8480410090


塑料制品(塑料件)海关编码为:39269090
模具一般按用途来归海关编码 请告诉具体用途 下面是按用途或制作材料的模具叫法,在实际报关中可以用制作对象的名称来命名,例如 刹车座模具 属于压膜 报关时可以用刹车座模具来报关,模具应该属于金属模具(压铸模具) 84804100
以下是模具的分类:
工具类:
金属拉拔 挤压用模具 82072090
锻压 冲压冲孔用模具 82073000
机器类:
1.   84389000  糖果模具
2.   84490090  铝制模具(制作帽子模具)
3.   84669300  钻孔定位模具(用于加工割草机零部件钻孔定位用)
4.   84801000  浇铸用模具
5.   84804100  金属模具(压铸模具 金属注模)
6.   84804900  金属模具(除上面   浇铸用模具   压铸模具 金属注模 外的其他金属铸造用模具)
7.   84805000  玻璃定形模具
8.   84807100  注塑模具 (压模 注模)
9.   84807900  吹塑模具 滚塑模具 挤出模具 发泡模具
现在海关编码是10位,可以在海关网查询更细的分类。

简单地说就是用我司名义进出口,由我司提供全套出口报关资料:核销单;合同;发票;装箱单;报关委托书;重柜纸;报关单;其他必须证书:如商检证、植检证、许可证、配额等;作为配套出口服务项目,我们根据《中华人民共和国海关管理条例》通过合法、正当手续办理货物进出口。因单证所发生的问题将由我公司负责。