Habr, xin chào! Hôm qua trên
Giới thiệu một chút về cách chúng tôi sử dụng Spark. Chúng tôi có chương trình ba tháng
Điểm đặc biệt trong việc sử dụng của chúng tôi là số lượng người làm việc đồng thời trên Spark có thể bằng cả nhóm. Ví dụ, tại một buổi hội thảo, khi mọi người cùng cố gắng làm một việc gì đó và lặp lại theo giáo viên của chúng ta. Và con số này không nhiều - đôi khi lên tới 40 người. Có lẽ không có nhiều công ty trên thế giới gặp phải trường hợp sử dụng như vậy.
Tiếp theo, tôi sẽ cho bạn biết cách thức và lý do chúng tôi chọn các thông số cấu hình nhất định.
Hãy bắt đầu lại từ đầu. Spark có 3 tùy chọn để chạy trên một cụm: độc lập, sử dụng Mesos và sử dụng YARN. Chúng tôi quyết định chọn phương án thứ ba vì nó có ý nghĩa đối với chúng tôi. Chúng tôi đã có một cụm hadoop. Những người tham gia của chúng tôi đã quen với kiến trúc của nó. Hãy sử dụng YARN.
spark.master=yarn
Hơn nữa thú vị hơn. Mỗi tùy chọn triển khai trong số 3 tùy chọn này đều có 2 tùy chọn triển khai: máy khách và cụm. Dựa trên
spark.deploy-mode=client
Nói chung, từ giờ trở đi Spark sẽ bằng cách nào đó hoạt động trên YARN, nhưng đối với chúng tôi điều này là chưa đủ. Vì chúng tôi có một chương trình về dữ liệu lớn nên đôi khi những người tham gia không có đủ những gì thu được trong khuôn khổ chia đều tài nguyên. Và sau đó chúng tôi tìm thấy một điều thú vị - phân bổ nguồn lực động. Tóm lại, vấn đề là thế này: nếu bạn gặp một nhiệm vụ khó khăn và cụm này trống (ví dụ: vào buổi sáng), thì việc sử dụng tùy chọn này Spark có thể cung cấp cho bạn thêm tài nguyên. Sự cần thiết được tính toán ở đó theo một công thức xảo quyệt. Chúng tôi sẽ không đi vào chi tiết - nó hoạt động tốt.
spark.dynamicAllocation.enabled=true
Chúng tôi đặt tham số này và khi khởi động Spark bị lỗi và không khởi động. Đúng rồi, vì tôi phải đọc nó
spark.shuffle.service.enabled=true
Tại sao nó lại cần thiết? Khi công việc của chúng ta không còn cần nhiều tài nguyên nữa, Spark nên đưa chúng trở lại nhóm chung. Giai đoạn tốn nhiều thời gian nhất trong hầu hết mọi nhiệm vụ MapReduce là giai đoạn Shuffle. Tham số này cho phép bạn lưu dữ liệu được tạo ở giai đoạn này và giải phóng các trình thực thi tương ứng. Và người thực thi là quá trình tính toán mọi thứ trên công nhân. Nó có một số lõi xử lý nhất định và một lượng bộ nhớ nhất định.
Tham số này đã được thêm vào. Mọi thứ dường như đã thành công. Điều đáng chú ý là những người tham gia thực sự được cung cấp nhiều tài nguyên hơn khi họ cần. Nhưng một vấn đề khác lại nảy sinh - đến một lúc nào đó, những người tham gia khác thức dậy và cũng muốn sử dụng Spark, nhưng ở đó mọi thứ đều bận rộn và họ không hài lòng. Chúng có thể được hiểu. Chúng tôi bắt đầu xem xét tài liệu. Hóa ra có một số thông số khác có thể được sử dụng để tác động đến quá trình. Ví dụ: nếu người thực thi ở chế độ chờ thì tài nguyên có thể được lấy từ nó sau bao lâu?
spark.dynamicAllocation.executorIdleTimeout=120s
Trong trường hợp của chúng tôi, nếu người thi hành của bạn không làm gì trong hai phút thì vui lòng đưa họ trở lại nhóm chung. Nhưng thông số này không phải lúc nào cũng đủ. Rõ ràng là người đó đã không làm gì trong một thời gian dài và tài nguyên cũng không được giải phóng. Hóa ra cũng có một tham số đặc biệt - sau thời gian nào để chọn bộ thực thi có chứa dữ liệu được lưu trong bộ nhớ cache. Theo mặc định, tham số này là vô cùng! Chúng tôi đã sửa nó.
spark.dynamicAllocation.cachedExecutorIdleTimeout=600s
Nghĩa là, nếu người thi hành án của bạn không làm gì trong 5 phút, hãy đưa họ vào nhóm chung. Ở chế độ này, tốc độ giải phóng và cấp tài nguyên cho số lượng lớn người dùng đã trở nên khá tốt. Mức độ bất mãn đã giảm đi. Nhưng chúng tôi đã quyết định đi xa hơn và giới hạn số lượng người thực thi tối đa cho mỗi ứng dụng - về cơ bản là cho mỗi người tham gia chương trình.
spark.dynamicAllocation.maxExecutors=19
Tất nhiên, bây giờ ở phía bên kia có những người không hài lòng - "cụm không hoạt động và tôi chỉ có 19 người thực thi", nhưng bạn có thể làm gì? Chúng ta cần một số loại cân bằng chính xác. Bạn không thể làm cho tất cả mọi người hạnh phúc.
Và một câu chuyện nhỏ nữa liên quan đến chi tiết vụ án của chúng tôi. Bằng cách nào đó, một số người đã đến muộn trong buổi học thực tế và vì lý do nào đó Spark đã không bắt đầu cho họ. Chúng tôi đã xem xét số lượng tài nguyên miễn phí - có vẻ như nó ở đó. Spark nên bắt đầu. May mắn thay, vào thời điểm đó tài liệu đã được thêm vào vỏ não ở đâu đó và chúng tôi nhớ rằng khi khởi chạy, Spark sẽ tìm kiếm một cổng để bắt đầu. Nếu cổng đầu tiên trong phạm vi bận, nó sẽ chuyển sang cổng tiếp theo theo thứ tự. Nếu nó miễn phí, nó sẽ nắm bắt. Và có một tham số cho biết số lần thử tối đa cho việc này. Mặc định là 16. Con số này ít hơn số người trong nhóm chúng tôi trong lớp. Theo đó, sau 16 lần thử, Spark đã bỏ cuộc và nói rằng tôi không thể bắt đầu được. Chúng tôi đã sửa cài đặt này.
spark.port.maxRetries=50
Tiếp theo tôi sẽ cho bạn biết về một số cài đặt không liên quan nhiều đến chi tiết cụ thể trong trường hợp của chúng tôi.
Để khởi động Spark nhanh hơn, bạn nên lưu trữ thư mục jars nằm trong thư mục chính SPARK_HOME và đặt nó trên HDFS. Sau đó, anh ta sẽ không lãng phí thời gian để công nhân tải những chiếc bình này.
spark.yarn.archive=hdfs:///tmp/spark-archive.zip
Bạn cũng nên sử dụng kryo làm bộ nối tiếp để hoạt động nhanh hơn. Nó được tối ưu hóa hơn so với mặc định.
spark.serializer=org.apache.spark.serializer.KryoSerializer
Và còn một vấn đề tồn tại từ lâu với Spark đó là nó hay bị treo từ bộ nhớ. Thường thì điều này xảy ra vào thời điểm công nhân đã tính toán xong mọi việc và gửi kết quả cho tài xế. Chúng tôi đã làm cho thông số này lớn hơn cho chính mình. Theo mặc định, nó là 1GB, chúng tôi đã tạo thành 3.
spark.driver.maxResultSize=3072
Và cuối cùng, như một món tráng miệng. Cách cập nhật Spark lên phiên bản 2.1 trên bản phân phối HortonWorks - HDP 2.5.3.0. Phiên bản HDP này chứa phiên bản 2.0 được cài đặt sẵn, nhưng chúng tôi đã từng tự quyết định rằng Spark đang phát triển khá tích cực và mỗi phiên bản mới đều sửa một số lỗi và cung cấp các tính năng bổ sung, bao gồm cả API python, vì vậy chúng tôi đã quyết định những gì cần phải làm được thực hiện là một bản cập nhật.
Đã tải xuống phiên bản từ trang web chính thức cho Hadoop 2.7. Giải nén và cho vào thư mục HDP. Chúng tôi đã cài đặt các liên kết tượng trưng khi cần thiết. Chúng tôi khởi chạy nó - nó không bắt đầu. Viết một lỗi rất không rõ ràng.
java.lang.NoClassDefFoundError: com/sun/jersey/api/client/config/ClientConfig
Sau khi tìm kiếm trên Google, chúng tôi phát hiện ra rằng Spark đã quyết định không đợi cho đến khi Hadoop ra đời mà quyết định sử dụng phiên bản jersey mới. Chính họ cũng tranh luận với nhau về chủ đề này trong JIRA. Giải pháp là tải xuống
Chúng tôi đã khắc phục được lỗi này nhưng lại xuất hiện một lỗi mới và khá hợp lý.
org.apache.spark.SparkException: Yarn application has already ended! It might have been killed or unable to launch application master
Đồng thời, chúng tôi thử chạy phiên bản 2.0 - mọi thứ đều ổn. Hãy thử đoán xem chuyện gì đang xảy ra. Chúng tôi đã xem xét nhật ký của ứng dụng này và thấy một cái gì đó như thế này:
/usr/hdp/${hdp.version}/hadoop/lib/hadoop-lzo-0.6.0.${hdp.version}.jar
Nói chung, vì lý do nào đó hdp.version không giải quyết được. Sau khi googling, chúng tôi tìm thấy một giải pháp. Bạn cần đi tới cài đặt YARN trong Ambari và thêm tham số ở đó vào trang sợi tùy chỉnh:
hdp.version=2.5.3.0-37
Phép thuật này đã giúp ích và Spark đã thành công. Chúng tôi đã thử nghiệm một số máy tính xách tay jupyter của chúng tôi. Mọi thứ đang hoạt động. Chúng ta đã sẵn sàng cho buổi học Spark đầu tiên vào thứ Bảy (ngày mai)!
CẬP NHẬT. Trong giờ học, một vấn đề khác lại được phát hiện. Tại một thời điểm nào đó, YARN đã ngừng cung cấp vùng chứa cho Spark. Trong YARN cần phải sửa tham số, theo mặc định là 0.2:
yarn.scheduler.capacity.maximum-am-resource-percent=0.8
Tức là chỉ có 20% tài nguyên tham gia vào việc phân phối tài nguyên. Sau khi thay đổi các tham số, chúng tôi tải lại YARN. Sự cố đã được giải quyết và những người tham gia còn lại cũng có thể chạy bối cảnh tia lửa.
Nguồn: www.habr.com